From be3dba2d825ddc11e83688d8b572b6fa166a12d9 Mon Sep 17 00:00:00 2001 From: gez Date: Sat, 16 Oct 2010 11:37:15 +0000 Subject: [PATCH 01/82] * Updated to ZDoom r2946: - Fixed some GCC problems with d_iwad.cpp. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1050 b0f79afe-0144-0410-b225-9a4edf0717df --- src/d_iwad.cpp | 5 +++-- src/svnrevision.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 93ea1083..d03507bf 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -233,7 +233,8 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize) // check for lowercase, uppercased first letter and full uppercase on Linux etc. wadname.ToLower(); mIWadNames.Push(wadname); - wadname[0] = toupper(wadname[0]); + wadname.LockBuffer()[0] = toupper(wadname[0]); + wadname.UnlockBuffer(); mIWadNames.Push(wadname); wadname.ToUpper(); mIWadNames.Push(wadname); @@ -331,7 +332,7 @@ int FIWadManager::CheckIWAD (const char *doomwaddir, WadStuff *wads) { FString iwad; - iwad.Format ("%s%s%s", doomwaddir, slash, mIWadNames[i]); + iwad.Format ("%s%s%s", doomwaddir, slash, mIWadNames[i].GetChars()); FixPathSeperator (iwad); if (FileExists (iwad)) { diff --git a/src/svnrevision.h b/src/svnrevision.h index cd8368a1..b0a989ca 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2941" -#define ZD_SVN_REVISION_NUMBER 2941 +#define ZD_SVN_REVISION_STRING "2946" +#define ZD_SVN_REVISION_NUMBER 2946 From 92065890fbb0be4ddb83ed8e708b535a091d5973 Mon Sep 17 00:00:00 2001 From: gez Date: Sat, 16 Oct 2010 17:54:54 +0000 Subject: [PATCH 02/82] * Updated to ZDoom r2948: - Fixed: Crash in Linux due to passing FStrings as character arrays. - Fixed: More places where SBarInfo used the unscaled information from graphics. - Fixed: The alternative HUD's number printing function did not take texture scaling into account when calculating the printing position. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1051 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_shared/sbarinfo.cpp | 4 ++-- src/g_shared/sbarinfo_commands.cpp | 2 +- src/g_shared/shared_hud.cpp | 13 ++++++++----- src/keysections.cpp | 2 +- src/sdl/i_system.cpp | 4 ++-- src/svnrevision.h | 4 ++-- src/textures/textures.h | 8 ++++---- 7 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index f31fb491..ee29a3b5 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -1153,8 +1153,8 @@ public: if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER) { - dx -= (texture->GetScaledWidthDouble()/2.0)-texture->LeftOffset; - dy -= (texture->GetScaledHeightDouble()/2.0)-texture->TopOffset; + dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(); + dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(); } dx += xOffset; diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 3b612368..fcc5a6e1 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -2730,7 +2730,7 @@ class CommandDrawGem : public SBarInfoCommand SBarInfoCoordinate drawY = y; if(wiggle && drawValue != goalValue) // Should only wiggle when the value doesn't equal what is being drawn. drawY += chainWiggle; - int chainWidth = chainImg->GetWidth(); + int chainWidth = chainImg->GetScaledWidth(); int offset = (int) (((double) (chainWidth-leftPadding-rightPadding)/100)*drawValue); statusBar->DrawGraphic(chainImg, x+(offset%chainSize), drawY, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); if(gemImg != NULL) diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 31dc116a..f82e866f 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -124,16 +124,16 @@ void SetHUDIcon(PClass *cls, FTextureID tex) //--------------------------------------------------------------------------- static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans=0xc000) { - float scale1, scale2; + double scale1, scale2; if (tex) { int texwidth=tex->GetWidth(); int texheight=tex->GetHeight(); - if (wGetChar(text[i], &width); if (texc != NULL) { - int offset = texc->TopOffset - tex_zero->TopOffset + tex_zero->GetHeight(); + double offset = texc->GetScaledTopOffsetDouble() + - tex_zero->GetScaledTopOffsetDouble() + + tex_zero->GetScaledHeightDouble(); + screen->DrawChar(font, color, x, y, text[i], DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans, - DTA_LeftOffset, width/2, DTA_TopOffset, offset, + DTA_LeftOffset, width/2, DTA_TopOffsetF, offset, /*DTA_CenterBottomOffset, 1,*/ TAG_DONE); } x += zerowidth; diff --git a/src/keysections.cpp b/src/keysections.cpp index 60afce21..6ef0538f 100644 --- a/src/keysections.cpp +++ b/src/keysections.cpp @@ -48,7 +48,7 @@ static void LoadKeys (const char *modname, bool dbl) { char section[64]; - mysnprintf (section, countof(section), "%s.%s%sBindings", gameinfo.ConfigName, modname, + mysnprintf (section, countof(section), "%s.%s%sBindings", gameinfo.ConfigName.GetChars(), modname, dbl ? ".Double" : "."); FKeyBindings *bindings = dbl? &DoubleBindings : &Bindings; diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 1a681fd6..6fc29665 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -511,7 +511,7 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad) gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, 0, filepart, - 1, wads[i].Name, + 1, wads[i].Name.GetChars(), 2, i, -1); if (i == defaultiwad) @@ -625,7 +625,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) filepart = wads[i].Path; else filepart++; - printf ("%d. %s (%s)\n", i+1, wads[i].Name, filepart); + printf ("%d. %s (%s)\n", i+1, wads[i].Name.GetChars(), filepart); } printf ("Which one? "); scanf ("%d", &i); diff --git a/src/svnrevision.h b/src/svnrevision.h index b0a989ca..1a3e7e67 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2946" -#define ZD_SVN_REVISION_NUMBER 2946 +#define ZD_SVN_REVISION_STRING "2948" +#define ZD_SVN_REVISION_NUMBER 2948 diff --git a/src/textures/textures.h b/src/textures/textures.h index 90d5b353..61838a80 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -205,13 +205,13 @@ public: int GetScaledWidth () { int foo = (Width << 17) / xScale; return (foo >> 1) + (foo & 1); } int GetScaledHeight () { int foo = (Height << 17) / yScale; return (foo >> 1) + (foo & 1); } - double GetScaledWidthDouble () { return (Width * 65536.f) / xScale; } - double GetScaledHeightDouble () { return (Height * 65536.f) / yScale; } + double GetScaledWidthDouble () { return (Width * 65536.) / xScale; } + double GetScaledHeightDouble () { return (Height * 65536.) / yScale; } int GetScaledLeftOffset () { int foo = (LeftOffset << 17) / xScale; return (foo >> 1) + (foo & 1); } int GetScaledTopOffset () { int foo = (TopOffset << 17) / yScale; return (foo >> 1) + (foo & 1); } - double GetScaledLeftOffsetDouble() { return (LeftOffset * 65536.f) / xScale; } - double GetScaledTopOffsetDouble() { return (TopOffset * 65536.f) / yScale; } + double GetScaledLeftOffsetDouble() { return (LeftOffset * 65536.) / xScale; } + double GetScaledTopOffsetDouble() { return (TopOffset * 65536.) / yScale; } virtual void SetFrontSkyLayer(); From c91dc68eba1f045fe2a26130445a243e642d4620 Mon Sep 17 00:00:00 2001 From: gez Date: Sat, 16 Oct 2010 22:47:18 +0000 Subject: [PATCH 03/82] * Updated to ZDoom r2950: - Fixed: Detection of MAP01 presence was wrong. - Externalized the vector graphics for the automap arrows and the key. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1052 b0f79afe-0144-0410-b225-9a4edf0717df --- src/am_map.cpp | 138 +++++++++++---------------- src/d_main.cpp | 2 +- src/gi.cpp | 11 +++ src/gi.h | 1 + src/svnrevision.h | 4 +- wadsrc/static/maparrows/arrow.txt | 7 ++ wadsrc/static/maparrows/dagger.txt | 10 ++ wadsrc/static/maparrows/ddtarrow.txt | 16 ++++ wadsrc/static/maparrows/key.txt | 12 +++ wadsrc/static/mapinfo/chex.txt | 1 + wadsrc/static/mapinfo/doomcommon.txt | 1 + wadsrc/static/mapinfo/heretic.txt | 1 + wadsrc/static/mapinfo/hexen.txt | 1 + wadsrc/static/mapinfo/strife.txt | 1 + 14 files changed, 122 insertions(+), 84 deletions(-) create mode 100644 wadsrc/static/maparrows/arrow.txt create mode 100644 wadsrc/static/maparrows/dagger.txt create mode 100644 wadsrc/static/maparrows/ddtarrow.txt create mode 100644 wadsrc/static/maparrows/key.txt diff --git a/src/am_map.cpp b/src/am_map.cpp index 45cb3f98..ce2c5597 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -287,53 +287,9 @@ struct islope_t // A line drawing of the player pointing right, // starting from the middle. // -#define R ((8*PLAYERRADIUS)/7) -mline_t player_arrow[] = { - { { -R+R/8, 0 }, { R, 0 } }, // ----- - { { R, 0 }, { R-R/2, R/4 } }, // -----> - { { R, 0 }, { R-R/2, -R/4 } }, - { { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >----> - { { -R+R/8, 0 }, { -R-R/8, -R/4 } }, - { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>---> - { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } } -}; -#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t)) - -mline_t player_arrow_raven[] = { - { { -R+R/4, 0 }, { 0, 0} }, // center line. - { { -R+R/4, R/8 }, { R, 0} }, // blade - { { -R+R/4, -R/8 }, { R, 0 } }, - { { -R+R/4, -R/4 }, { -R+R/4, R/4 } }, // crosspiece - { { -R+R/8, -R/4 }, { -R+R/8, R/4 } }, - { { -R+R/8, -R/4 }, { -R+R/4, -R/4} }, //crosspiece connectors - { { -R+R/8, R/4 }, { -R+R/4, R/4} }, - { { -R-R/4, R/8 }, { -R-R/4, -R/8 } }, //pommel - { { -R-R/4, R/8 }, { -R+R/8, R/8 } }, - { { -R-R/4, -R/8}, { -R+R/8, -R/8 } } -}; -#define NUMPLYRLINES_RAVEN (sizeof(player_arrow_raven)/sizeof(mline_t)) - -mline_t cheat_player_arrow[] = { - { { -R+R/8, 0 }, { R, 0 } }, // ----- - { { R, 0 }, { R-R/2, R/6 } }, // -----> - { { R, 0 }, { R-R/2, -R/6 } }, - { { -R+R/8, 0 }, { -R-R/8, R/6 } }, // >-----> - { { -R+R/8, 0 }, { -R-R/8, -R/6 } }, - { { -R+3*R/8, 0 }, { -R+R/8, R/6 } }, // >>-----> - { { -R+3*R/8, 0 }, { -R+R/8, -R/6 } }, - { { -R/2, 0 }, { -R/2, -R/6 } }, // >>-d---> - { { -R/2, -R/6 }, { -R/2+R/6, -R/6 } }, - { { -R/2+R/6, -R/6 }, { -R/2+R/6, R/4 } }, - { { -R/6, 0 }, { -R/6, -R/6 } }, // >>-dd--> - { { -R/6, -R/6 }, { 0, -R/6 } }, - { { 0, -R/6 }, { 0, R/4 } }, - { { R/6, R/4 }, { R/6, -R/7 } }, // >>-ddt-> - { { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } }, - { { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } } -}; -#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t)) - -#undef R +TArray MapArrow; +TArray CheatMapArrow; +TArray CheatKey; #define R (MAPUNIT) // [RH] Avoid lots of warnings without compiler-specific #pragmas @@ -361,26 +317,6 @@ mline_t square_guy[] = { #define NUMSQUAREGUYLINES (sizeof(square_guy)/sizeof(mline_t)) #undef R -#define R (MAPUNIT) - -mline_t key_guy[] = { - L (-2, 0, -1.7, -0.5), - L (-1.7, -0.5, -1.5, -0.7), - L (-1.5, -0.7, -0.8, -0.5), - L (-0.8, -0.5, -0.6, 0), - L (-0.6, 0, -0.8, 0.5), - L (-1.5, 0.7, -0.8, 0.5), - L (-1.7, 0.5, -1.5, 0.7), - L (-2, 0, -1.7, 0.5), - L (-0.6, 0, 2, 0), - L (1.7, 0, 1.7, -1), - L (1.5, 0, 1.5, -1), - L (1.3, 0, 1.3, -1) -}; -#define NUMKEYGUYLINES (sizeof(key_guy)/sizeof(mline_t)) - -#undef L -#undef R @@ -545,6 +481,51 @@ void AM_getIslope (mline_t *ml, islope_t *is) } */ + +void AM_ParseArrow(TArray &Arrow, const char *lumpname) +{ + const int R = ((8*PLAYERRADIUS)/7); + FScanner sc; + int lump = Wads.CheckNumForFullName(lumpname, true); + if (lump >= 0) + { + sc.OpenLumpNum(lump); + sc.SetCMode(true); + while (sc.GetToken()) + { + mline_t line; + sc.TokenMustBe('('); + sc.MustGetFloat(); + line.a.x = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(','); + sc.MustGetFloat(); + line.a.y = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(')'); + sc.MustGetToken(','); + sc.MustGetToken('('); + sc.MustGetFloat(); + line.b.x = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(','); + sc.MustGetFloat(); + line.b.y = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(')'); + Arrow.Push(line); + } + } +} + +void AM_InitArrows() +{ + + MapArrow.Clear(); + CheatMapArrow.Clear(); + + if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow); + if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow); + AM_ParseArrow(CheatKey, "maparrows/key.txt"); + if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined"); +} + //============================================================================= // // called by the coordinate drawer @@ -1066,6 +1047,8 @@ bool AM_clearMarks () void AM_LevelInit () { + if (MapArrow.Size() == 0) AM_InitArrows(); + leveljuststarted = 0; AM_clearMarks(); @@ -2047,20 +2030,15 @@ void AM_drawPlayers () angle = players[consoleplayer].camera->angle; } - if (gameinfo.gametype & GAME_Raven) + if (am_cheat != 0 && CheatMapArrow.Size() > 0) { - arrow = player_arrow_raven; - numarrowlines = NUMPLYRLINES_RAVEN; - } - else if (am_cheat != 0) - { - arrow = cheat_player_arrow; - numarrowlines = NUMCHEATPLYRLINES; + arrow = &CheatMapArrow[0]; + numarrowlines = CheatMapArrow.Size(); } else { - arrow = player_arrow; - numarrowlines = NUMPLYRLINES; + arrow = &MapArrow[0]; + numarrowlines = MapArrow.Size(); } AM_drawLineCharacter(arrow, numarrowlines, 0, angle, YourColor, pt.x, pt.y); return; @@ -2113,9 +2091,7 @@ void AM_drawPlayers () angle -= players[consoleplayer].camera->angle - ANG90; } - AM_drawLineCharacter - (player_arrow, NUMPLYRLINES, 0, angle, - color, pt.x, pt.y); + AM_drawLineCharacter(&MapArrow[0], MapArrow.Size(), 0, angle, color, pt.x, pt.y); } } } @@ -2171,7 +2147,7 @@ void AM_drawThings () if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); else color = ThingColor_CountItem; - AM_drawLineCharacter(key_guy, NUMKEYGUYLINES, 16< & pwads) static void SetMapxxFlag() { - int lump_name = Wads.CheckNumForName("MAP01", FWadCollection::IWAD_FILENUM); + int lump_name = Wads.CheckNumForName("MAP01", ns_global, FWadCollection::IWAD_FILENUM); int lump_wad = Wads.CheckNumForFullName("maps/map01.wad", FWadCollection::IWAD_FILENUM); int lump_map = Wads.CheckNumForFullName("maps/map01.map", FWadCollection::IWAD_FILENUM); diff --git a/src/gi.cpp b/src/gi.cpp index 18f8a667..4dfac16f 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -247,6 +247,17 @@ void FMapInfoParser::ParseGameInfo() gameinfo.ArmorIcon2[8] = 0; } } + else if(nextKey.CompareNoCase("maparrow") == 0) + { + sc.MustGetToken(TK_StringConst); + gameinfo.mMapArrow = sc.String; + if (sc.CheckToken(',')) + { + sc.MustGetToken(TK_StringConst); + gameinfo.mCheatMapArrow = sc.String; + } + else gameinfo.mCheatMapArrow = ""; + } // Insert valid keys here. GAMEINFOKEY_CSTRING(titlePage, "titlePage", 8) GAMEINFOKEY_STRINGARRAY(creditPages, "creditPage", 8) diff --git a/src/gi.h b/src/gi.h index 7559a2c4..d9422c03 100644 --- a/src/gi.h +++ b/src/gi.h @@ -129,6 +129,7 @@ struct gameinfo_t int TextScreenX; int TextScreenY; FName DefaultEndSequence; + FString mMapArrow, mCheatMapArrow; const char *GetFinalePage(unsigned int num) const; }; diff --git a/src/svnrevision.h b/src/svnrevision.h index 1a3e7e67..21fa00e6 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2948" -#define ZD_SVN_REVISION_NUMBER 2948 +#define ZD_SVN_REVISION_STRING "2950" +#define ZD_SVN_REVISION_NUMBER 2950 diff --git a/wadsrc/static/maparrows/arrow.txt b/wadsrc/static/maparrows/arrow.txt new file mode 100644 index 00000000..742d344e --- /dev/null +++ b/wadsrc/static/maparrows/arrow.txt @@ -0,0 +1,7 @@ +(-0.875, 0), (1, 0) // ----- +(1, 0), (0.5, 0.25) // -----> +(1, 0), (0.5, -0.25) +(-0.875, 0), (-1.125, -0.25) // >----> +(-0.875, 0), (-1.125, 0.25) +(-0.625, 0), (-0.875, -0.25) // >>---> +(-0.625, 0), (-0.875, 0.25) diff --git a/wadsrc/static/maparrows/dagger.txt b/wadsrc/static/maparrows/dagger.txt new file mode 100644 index 00000000..0c16efc5 --- /dev/null +++ b/wadsrc/static/maparrows/dagger.txt @@ -0,0 +1,10 @@ +(-0.75, 0), (0, 0) // center line. +(-0.75, 0.125), (1, 0) // blade +(-0.75, -0.125), (1, 0 ) +(-0.75, -0.25), (-0.75, 0.25 ) // crosspiece +(-0.875, -0.25), (-0.875, 0.25 ) +(-0.875, -0.25), (-0.75, -0.25) //crosspiece connectors +(-0.875, 0.25), (-0.75, 0.25) +(-1.125, 0.125), (-1.125, -0.125 ) //pommel +(-1.125, 0.125), (-0.875, 0.125 ) +(-1.125, -0.125), (-0.875, -0.125) diff --git a/wadsrc/static/maparrows/ddtarrow.txt b/wadsrc/static/maparrows/ddtarrow.txt new file mode 100644 index 00000000..51919c72 --- /dev/null +++ b/wadsrc/static/maparrows/ddtarrow.txt @@ -0,0 +1,16 @@ +(-0.875, 0), (1, 0) // ----- +(1, 0), (0.5, 0.167) // -----> +(1, 0), (0.5, -0.167) +(-0.875, 0), (-1.125, -0.167) // >----> +(-0.875, 0), (-1.125, 0.167) +(-0.625, 0), (-0.875, -0.167) // >>---> +(-0.625, 0), (-0.875, 0.167) +(-0.5, 0), (-0.5, -0.167) // >>-d---> +(-0.5, -0.167), (-0.333, -0.167) +(-0.333, -0.167), (-0.333, 0.25) +(-0.167, 0), (-0.167, -0.167) // >>-dd--> +(-0.167, -0.167), (0, -0.167) +(0, -0.167), (0, 0.25) +(0.167, 0.25), (0.167, -0.143) // >>-ddt-> +(0.167, -0.143), (0.198, -0.174) +(0.198, -0.174), (0.267, -0.143) diff --git a/wadsrc/static/maparrows/key.txt b/wadsrc/static/maparrows/key.txt new file mode 100644 index 00000000..f252d0bf --- /dev/null +++ b/wadsrc/static/maparrows/key.txt @@ -0,0 +1,12 @@ +(-2, 0), (-1.7, -0.5) +(-1.7, -0.5), (-1.5, -0.7) +(-1.5, -0.7), (-0.8, -0.5) +(-0.8, -0.5), (-0.6, 0) +(-0.6, 0), (-0.8, 0.5) +(-1.5, 0.7), (-0.8, 0.5) +(-1.7, 0.5), (-1.5, 0.7) +(-2, 0), (-1.7, 0.5) +(-0.6, 0), (2, 0) +(1.7, 0), (1.7, -1) +(1.5, 0), (1.5, -1) +(1.3, 0), (1.3, -1) diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index 7ff6e2d6..79f27f5b 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -60,6 +60,7 @@ gameinfo textscreenx = 10 textscreeny = 10 defaultendsequence = "Inter_Pic1" + maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt" } skill baby diff --git a/wadsrc/static/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt index 0ad964ca..73d00379 100644 --- a/wadsrc/static/mapinfo/doomcommon.txt +++ b/wadsrc/static/mapinfo/doomcommon.txt @@ -61,6 +61,7 @@ gameinfo textscreenx = 10 textscreeny = 10 defaultendsequence = "Inter_Cast" + maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt" } skill baby diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 0e269c8f..57aa839f 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -60,6 +60,7 @@ gameinfo textscreenx = 20 textscreeny = 5 defaultendsequence = "Inter_Pic1" + maparrow = "maparrows/dagger.txt" } skill baby diff --git a/wadsrc/static/mapinfo/hexen.txt b/wadsrc/static/mapinfo/hexen.txt index 6022c541..eeef3b92 100644 --- a/wadsrc/static/mapinfo/hexen.txt +++ b/wadsrc/static/mapinfo/hexen.txt @@ -58,6 +58,7 @@ gameinfo textscreenx = 10 textscreeny = 5 defaultendsequence = "Inter_Chess" + maparrow = "maparrows/dagger.txt" } skill baby diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index aed50b22..2e6c242c 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -60,6 +60,7 @@ gameinfo textscreenx = 10 textscreeny = 10 defaultendsequence = "Inter_Strife" + maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt" } Intermission Inter_Strife_Good From c2475f3484a29f808e3475ce581b3af365981a01 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Oct 2010 13:05:23 +0000 Subject: [PATCH 04/82] - should have been in the trunk... git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1059 b0f79afe-0144-0410-b225-9a4edf0717df --- wadsrc/static/iwadinfo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index 0ee148b1..47001257 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -91,7 +91,7 @@ IWad Name = "Hexen: Beyond Heretic" Game = "Hexen" Config = "Hexen" - Mapinfo = "mapinfo/doom2.txt" + Mapinfo = "mapinfo/hexen.txt" Compatibility = "Poly1" MustContain = "TITLE", "MAP01", "MAP40", "WINNOWR" BannerColors = "f0 f0 f0", "6b 3c 18" From 31a0b421080a3af1f4696776412e0a6508cc9ceb Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 17 Oct 2010 20:04:27 +0000 Subject: [PATCH 05/82] * Updated to ZDoom r2955: - Fixed: The intermission data was never freed. - Let FPlayerNameBox::DrawBorder decide what graphics to use based on actual presence in the WADs, not the gamemode. - Added option for the cast call to use a 'Death.Cast' sequence so that monsters with an unusable death sequence for the cast call can define an alternative. - Fixed: The cast call could time out on overlong death sequences and get stuck. - Fixed: The cast call code should treat a waiting state in the death sequence as its end. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1061 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_mapinfo.cpp | 16 +++++++++++++++- src/intermission/intermission.cpp | 9 ++++++--- src/intermission/intermission.h | 3 ++- src/intermission/intermission_parse.cpp | 13 +++++++++++++ src/menu/playermenu.cpp | 21 ++++++++++++++++----- src/namedef.h | 7 +------ src/svnrevision.h | 4 ++-- 7 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index e15de22a..84b6aa48 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1787,6 +1787,20 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i } +//========================================================================== +// +// +// +//========================================================================== + +void DeinitIntermissions(); + +static void ClearMapinfo() +{ + ClearEpisodes(); + DeinitIntermissions(); +} + //========================================================================== // // G_ParseMapInfo @@ -1800,7 +1814,7 @@ void G_ParseMapInfo (const char *basemapinfo) int lump, lastlump = 0; level_info_t gamedefaults; - atterm(ClearEpisodes); + atterm(ClearMapinfo); // Parse the default MAPINFO for the current game. This lump *MUST* come from zdoom.pk3. if (basemapinfo != NULL) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index acb9fb62..8448bf00 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -433,7 +433,9 @@ int DIntermissionScreenCast::Responder (event_t *ev) return 1; // already in dying frames castdeath = true; - caststate = mClass->ActorInfo->FindState(NAME_Death); + + FName label[] = {NAME_Death, NAME_Cast}; + caststate = mClass->ActorInfo->FindState(2, label); if (caststate == NULL) return -1; casttics = caststate->GetTics(); @@ -478,7 +480,8 @@ int DIntermissionScreenCast::Ticker () if (--casttics > 0 && caststate != NULL) return 0; // not time to change state yet - if (caststate == NULL || caststate->GetTics() == -1 || caststate->GetNextState() == NULL) + if (caststate == NULL || caststate->GetTics() == -1 || caststate->GetNextState() == NULL || + caststate->GetNextState() == caststate) { return -1; } @@ -494,7 +497,7 @@ int DIntermissionScreenCast::Ticker () castframes++; } - if (castframes == 12) + if (castframes == 12 && !castdeath) { // go into attack frame castattacking = true; diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index 72dd5a2e..4298b54b 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -80,6 +80,7 @@ struct FIntermissionAction TArray mOverlays; FIntermissionAction(); + virtual ~FIntermissionAction() {} virtual bool ParseKey(FScanner &sc); }; @@ -145,7 +146,7 @@ struct FIntermissionActionScroller : public FIntermissionAction struct FIntermissionDescriptor { FName mLink; - TArray mActions; + TDeletingArray mActions; }; typedef TMap FIntermissionDescriptorList; diff --git a/src/intermission/intermission_parse.cpp b/src/intermission/intermission_parse.cpp index b7951986..bf6ae0dd 100644 --- a/src/intermission/intermission_parse.cpp +++ b/src/intermission/intermission_parse.cpp @@ -47,6 +47,19 @@ static void ReplaceIntermission(FName intname,FIntermissionDescriptor *desc) IntermissionDescriptors[intname] = desc; } +void DeinitIntermissions() +{ + FIntermissionDescriptorList::Iterator it(IntermissionDescriptors); + + FIntermissionDescriptorList::Pair *pair; + + while (it.NextPair(pair)) + { + delete pair->Value; + pair->Value = NULL; + } +} + //========================================================================== // // FIntermissionAction diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index c4ad7b86..03300af1 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -115,23 +115,34 @@ bool FPlayerNameBox::GetString(int i, char *s, int len) void FPlayerNameBox::DrawBorder (int x, int y, int len) { - if (gameinfo.gametype & (GAME_DoomStrifeChex)) + FTexture *left = TexMan[TexMan.CheckForTexture("M_LSLEFT", FTexture::TEX_MiscPatch)]; + FTexture *mid = TexMan[TexMan.CheckForTexture("M_LSCNTR", FTexture::TEX_MiscPatch)]; + FTexture *right = TexMan[TexMan.CheckForTexture("M_LSRGHT", FTexture::TEX_MiscPatch)]; + if (left != NULL && right != NULL && mid != NULL) { int i; - screen->DrawTexture (TexMan["M_LSLEFT"], x-8, y+7, DTA_Clean, true, TAG_DONE); + screen->DrawTexture (left, x-8, y+7, DTA_Clean, true, TAG_DONE); for (i = 0; i < len; i++) { - screen->DrawTexture (TexMan["M_LSCNTR"], x, y+7, DTA_Clean, true, TAG_DONE); + screen->DrawTexture (mid, x, y+7, DTA_Clean, true, TAG_DONE); x += 8; } - screen->DrawTexture (TexMan["M_LSRGHT"], x, y+7, DTA_Clean, true, TAG_DONE); + screen->DrawTexture (right, x, y+7, DTA_Clean, true, TAG_DONE); } else { - screen->DrawTexture (TexMan["M_FSLOT"], x, y+1, DTA_Clean, true, TAG_DONE); + FTexture *slot = TexMan[TexMan.CheckForTexture("M_FSLOT", FTexture::TEX_MiscPatch)]; + if (slot != NULL) + { + screen->DrawTexture (slot, x, y+1, DTA_Clean, true, TAG_DONE); + } + else + { + screen->Clear(x, y, x + len, y + SmallFont->GetHeight() * 3/2, -1, 0); + } } } diff --git a/src/namedef.h b/src/namedef.h index c9168fed..4a00c99c 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -105,12 +105,6 @@ xx(ArtiPoisonBag3) // Strife quests xx(QuestItem) -// Auto-usable health items -xx(ArtiHealth) -xx(ArtiSuperHealth) -xx(MedicalKit) -xx(MedPatch) - // Armor xx(BasicArmor) @@ -251,6 +245,7 @@ xx(PoisonCloud) // makes monsters howl. // a damage type if you wanted to force an extreme death. xx(Extreme) xx(MDK) +xx(Cast) // 'damage type' for the cast call // Special names for thingdef_exp.cpp xx(Random) diff --git a/src/svnrevision.h b/src/svnrevision.h index 21fa00e6..c842c10a 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2950" -#define ZD_SVN_REVISION_NUMBER 2950 +#define ZD_SVN_REVISION_STRING "2955" +#define ZD_SVN_REVISION_NUMBER 2955 From f50cbb09e8fcf5715b249774f74bb492b067e674 Mon Sep 17 00:00:00 2001 From: gez Date: Mon, 18 Oct 2010 09:07:21 +0000 Subject: [PATCH 06/82] * Updated to ZDoom r2957: - Fixed: States jumping to themselves should only end an actor's cast call when it happens in the death sequence. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1063 b0f79afe-0144-0410-b225-9a4edf0717df --- src/intermission/intermission.cpp | 2 +- src/svnrevision.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 8448bf00..f22df89f 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -481,7 +481,7 @@ int DIntermissionScreenCast::Ticker () return 0; // not time to change state yet if (caststate == NULL || caststate->GetTics() == -1 || caststate->GetNextState() == NULL || - caststate->GetNextState() == caststate) + (caststate->GetNextState() == caststate && castdeath)) { return -1; } diff --git a/src/svnrevision.h b/src/svnrevision.h index c842c10a..37fc703d 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2955" -#define ZD_SVN_REVISION_NUMBER 2955 +#define ZD_SVN_REVISION_STRING "2957" +#define ZD_SVN_REVISION_NUMBER 2957 From 6922d4da451d9354cb45b131568a38b2f68d44b5 Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 24 Oct 2010 08:40:22 +0000 Subject: [PATCH 07/82] * Updated to ZDoom r2965: - Made "follow player" automap option a CVAR and added a menu item for it. - Added a CVAR to decide when to show the map label (ExMy, MAPxx) on the automap HUD. Available settings are Never, Always and Not for hubs. - Made all crosshair related CVARs game specific. They were all global to all supportesd games. - Fixed: When used on non-projectiles A_Explode ignored the HurtSource flag. - Fixed: The intermission screen was not taking texture scaling into account (it was written before the introduction of scaled texture handling for 2D.) - Fixed: The GAMEINFO parser did not correctly handle NOSPRITERENAME - Added STTPRCNT to HUDFONT_DOOM git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1065 b0f79afe-0144-0410-b225-9a4edf0717df --- src/am_map.cpp | 17 ++++++------ src/d_main.cpp | 3 ++- src/g_shared/sbar.h | 1 + src/g_shared/shared_hud.cpp | 7 +++-- src/g_shared/shared_sbar.cpp | 51 +++++++++++++++++++++++++----------- src/p_map.cpp | 2 +- src/svnrevision.h | 4 +-- src/wi_stuff.cpp | 30 ++++++++++----------- wadsrc/static/fontdefs.txt | 1 + wadsrc/static/menudef.txt | 9 +++++++ 10 files changed, 78 insertions(+), 47 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index ce2c5597..2de0a5bc 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -385,8 +385,6 @@ static FTextureID marknums[10]; // numbers used for marking by the automap static mpoint_t markpoints[AM_NUMMARKPOINTS]; // where the points are static int markpointnum = 0; // next point to be assigned -static int followplayer = 1; // specifies whether to follow the player around - static FTextureID mapback; // the automap background static fixed_t mapystart=0; // y-value for the start of the map bitmap...used in the parallax stuff. static fixed_t mapxstart=0; //x-value for the bitmap. @@ -412,11 +410,14 @@ void AM_restoreScaleAndLoc (); void AM_minOutWindowScale (); +CVAR(Bool, am_followplayer, true, CVAR_ARCHIVE) + + CCMD(am_togglefollow) { - followplayer = !followplayer; + am_followplayer = !am_followplayer; f_oldloc.x = FIXED_MAX; - Printf ("%s\n", GStrings(followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); + Printf ("%s\n", GStrings(am_followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); } CCMD(am_togglegrid) @@ -580,7 +581,7 @@ void AM_restoreScaleAndLoc () { m_w = old_m_w; m_h = old_m_h; - if (!followplayer) + if (!am_followplayer) { m_x = old_m_x; m_y = old_m_y; @@ -777,7 +778,7 @@ void AM_changeWindowLoc () { if (0 != (m_paninc.x | m_paninc.y)) { - followplayer = 0; + am_followplayer = false; f_oldloc.x = FIXED_MAX; } @@ -1199,7 +1200,7 @@ bool AM_Responder (event_t *ev, bool last) { if (automapactive && (ev->type == EV_KeyDown || ev->type == EV_KeyUp)) { - if (followplayer) + if (am_followplayer) { // check for am_pan* and ignore in follow mode const char *defbind = AutomapBindings.GetBind(ev->data1); @@ -1312,7 +1313,7 @@ void AM_Ticker () amclock++; - if (followplayer) + if (am_followplayer) { AM_doFollowPlayer(); } diff --git a/src/d_main.cpp b/src/d_main.cpp index 26954b56..61400d8a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1723,7 +1723,8 @@ static FString ParseGameInfo(TArray &pwads, const char *fn, const char } else if (!nextKey.CompareNoCase("NOSPRITERENAME")) { - nospriterename = true; + sc.MustGetString(); + nospriterename = sc.Compare("true"); } else if (!nextKey.CompareNoCase("STARTUPTITLE")) { diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 295e0e4e..b2f6173b 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -381,6 +381,7 @@ DBaseStatusBar *CreateCustomStatusBar(int script=0); // Crosshair stuff ---------------------------------------------------------- +void ST_FormatMapName(FString &mapname, const char *mapnamecolor = ""); void ST_LoadCrosshair(bool alwaysload=false); extern FTexture *CrosshairImage; diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index f82e866f..d766d890 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -833,10 +833,9 @@ void DrawHUD() } else { + FString mapname; char printstr[256]; int seconds; - cluster_info_t *thiscluster = FindClusterInfo (level.cluster); - bool hub = !!(thiscluster->flags&CLUSTER_HUB); int length=8*SmallFont->GetCharWidth('0'); int fonth=SmallFont->GetHeight()+1; int bottom=hudheight-1; @@ -865,8 +864,8 @@ void DrawHUD() } } - mysnprintf(printstr, countof(printstr), "%s: %s", level.mapname, level.LevelName.GetChars()); - screen->DrawText(SmallFont, hudcolor_titl, 1, hudheight-fonth-1, printstr, + ST_FormatMapName(mapname); + screen->DrawText(SmallFont, hudcolor_titl, 1, hudheight-fonth-1, mapname, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index beb459cd..75084ae3 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -95,12 +95,16 @@ CUSTOM_CVAR (Bool, st_scale, true, CVAR_ARCHIVE) } } -CVAR (Int, crosshair, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, crosshairforce, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Color, crosshaircolor, 0xff0000, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR (Bool, crosshairhealth, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR (Bool, crosshairscale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR (Bool, crosshairgrow, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR (Int, crosshair, 0, CVAR_ARCHIVE) +CVAR (Bool, crosshairforce, false, CVAR_ARCHIVE) +CVAR (Color, crosshaircolor, 0xff0000, CVAR_ARCHIVE); +CVAR (Bool, crosshairhealth, true, CVAR_ARCHIVE); +CVAR (Bool, crosshairscale, false, CVAR_ARCHIVE); +CVAR (Bool, crosshairgrow, false, CVAR_ARCHIVE); +CUSTOM_CVAR(Int, am_showmaplabel, 2, CVAR_ARCHIVE) +{ + if (self < 0 || self > 2) self = 2; +} CVAR (Bool, idmypos, false, 0); @@ -118,6 +122,30 @@ BYTE DBaseStatusBar::DamageToAlpha[114] = 230, 231, 232, 233, 234, 235, 235, 236, 237 }; +//--------------------------------------------------------------------------- +// +// Format the map name, include the map label if wanted +// +//--------------------------------------------------------------------------- + +void ST_FormatMapName(FString &mapname, const char *mapnamecolor) +{ + cluster_info_t *cluster = FindClusterInfo (level.cluster); + bool ishub = (cluster != NULL && (cluster->flags & CLUSTER_HUB)); + + if (am_showmaplabel == 1 || (am_showmaplabel == 2 && !ishub)) + { + mapname << level.mapname << ": "; + } + mapname << mapnamecolor << level.LevelName; +} + +//--------------------------------------------------------------------------- +// +// Load crosshair definitions +// +//--------------------------------------------------------------------------- + void ST_LoadCrosshair(bool alwaysload) { int num = 0; @@ -1270,18 +1298,9 @@ void DBaseStatusBar::Draw (EHudState state) y -= 8; } } - cluster_info_t *cluster = FindClusterInfo (level.cluster); - if (cluster == NULL || !(cluster->flags & CLUSTER_HUB)) - { - mysnprintf (line, countof(line), "%s: ", level.mapname); - } - else - { - *line = 0; - } FString mapname; - mapname.Format("%s%c%c%s", line, TEXTCOLOR_ESCAPE, CR_GREY + 'A', level.LevelName.GetChars()); + ST_FormatMapName(mapname, TEXTCOLOR_GREY); screen->DrawText (SmallFont, highlight, (SCREENWIDTH - SmallFont->StringWidth (mapname)*CleanXfac)/2, y, mapname, DTA_CleanNoMove, true, TAG_DONE); diff --git a/src/p_map.cpp b/src/p_map.cpp index 424591be..3c791fea 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4325,7 +4325,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b if (thing->flags3 & MF3_NORADIUSDMG && !(bombspot->flags4 & MF4_FORCERADIUSDMG)) continue; - if (!DamageSource && thing == bombsource) + if (!DamageSource && (thing == bombsource || thing == bombspot)) { // don't damage the source of the explosion continue; } diff --git a/src/svnrevision.h b/src/svnrevision.h index 37fc703d..b27410f0 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2957" -#define ZD_SVN_REVISION_NUMBER 2957 +#define ZD_SVN_REVISION_STRING "2965" +#define ZD_SVN_REVISION_NUMBER 2965 diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 7c07ae78..42291681 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -79,7 +79,7 @@ void WI_unloadData (); // NET GAME STUFF #define NG_STATSY 50 -#define NG_STATSX (32 + star->GetWidth()/2 + 32*!dofrags) +#define NG_STATSX (32 + star->GetScaledWidth()/2 + 32*!dofrags) #define NG_SPACINGX 64 @@ -606,8 +606,8 @@ void WI_drawBackground() // scale all animations below to fit the size of the base pic // The base pic is always scaled to fit the screen so this allows // placing the animations precisely where they belong on the base pic - animwidth = background->GetScaledWidth(); - animheight = background->GetScaledHeight(); + animwidth = background->GetScaledWidthDouble(); + animheight = background->GetScaledHeightDouble(); screen->FillBorder (NULL); screen->DrawTexture(background, 0, 0, DTA_Fullscreen, true, TAG_DONE); } @@ -746,8 +746,8 @@ int WI_drawLF () // draw if (tex) { - screen->DrawTexture(tex, midx - tex->GetWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE); - y += (tex->GetHeight() + BigFont->GetHeight()/4) * CleanYfac; + screen->DrawTexture(tex, midx - tex->GetScaledWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE); + y += (tex->GetScaledHeight() + BigFont->GetHeight()/4) * CleanYfac; } else { @@ -761,8 +761,8 @@ int WI_drawLF () // don't draw 'finished' if the level name is too high! if (gameinfo.gametype & GAME_DoomChex) { - screen->DrawTexture(finished, midx - finished->GetWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE); - return y + finished->GetHeight() * CleanYfac; + screen->DrawTexture(finished, midx - finished->GetScaledWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE); + return y + finished->GetScaledHeight() * CleanYfac; } else { @@ -793,8 +793,8 @@ void WI_drawEL () // be careful with the added height so that it works for oversized 'entering' patches! if (gameinfo.gametype & GAME_DoomChex) { - screen->DrawTexture(entering, (SCREENWIDTH - entering->GetWidth() * CleanXfac) / 2, y, DTA_CleanNoMove, true, TAG_DONE); - y += (entering->GetHeight() + font->GetHeight()/4) * CleanYfac; + screen->DrawTexture(entering, (SCREENWIDTH - entering->GetScaledWidth() * CleanXfac) / 2, y, DTA_CleanNoMove, true, TAG_DONE); + y += (entering->GetScaledHeight() + font->GetHeight()/4) * CleanYfac; } else { @@ -808,7 +808,7 @@ void WI_drawEL () FTexture *tex = wbs->LName1; if (tex) { - screen->DrawTexture(tex, (SCREENWIDTH - tex->GetWidth() * CleanXfac) / 2, y, DTA_CleanNoMove, true, TAG_DONE); + screen->DrawTexture(tex, (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac) / 2, y, DTA_CleanNoMove, true, TAG_DONE); } else { @@ -853,10 +853,10 @@ void WI_drawOnLnode( int n, FTexture * c[] ,int numc) int bottom; - right = c[i]->GetWidth(); - bottom = c[i]->GetHeight(); - left = lnodes[n].x - c[i]->LeftOffset; - top = lnodes[n].y - c[i]->TopOffset; + right = c[i]->GetScaledWidth(); + bottom = c[i]->GetScaledHeight(); + left = lnodes[n].x - c[i]->GetScaledLeftOffset(); + top = lnodes[n].y - c[i]->GetScaledTopOffset(); right += left; bottom += top; @@ -980,7 +980,7 @@ void WI_drawTime (int x, int y, int t, bool no_sucks=false) { // "sucks" if (sucks != NULL) { - screen->DrawTexture (sucks, x - sucks->GetWidth(), y - IntermissionFont->GetHeight() - 2, + screen->DrawTexture (sucks, x - sucks->GetScaledWidth(), y - IntermissionFont->GetHeight() - 2, DTA_Clean, true, TAG_DONE); } else diff --git a/wadsrc/static/fontdefs.txt b/wadsrc/static/fontdefs.txt index 19e53eff..a8e99bb3 100644 --- a/wadsrc/static/fontdefs.txt +++ b/wadsrc/static/fontdefs.txt @@ -4,6 +4,7 @@ HUDFONT_DOOM { - STTMINUS + % STTPRCNT 0 STTNUM0 1 STTNUM1 2 STTNUM2 diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index db8d4bd4..4a577d90 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -841,6 +841,13 @@ OptionValue OverlayTypes 2, "Overlay Only" } +OptionValue MaplabelTypes +{ + 0, "Never" + 1, "Always" + 2, "Not for hubs" +} + OptionMenu AutomapOptions { Title "AUTOMAP OPTIONS" @@ -851,6 +858,7 @@ OptionMenu AutomapOptions Option "Rotate automap", "am_rotate", "RotateTypes" Option "Overlay automap", "am_overlay", "OverlayTypes" Option "Enable textured display", "am_textured", "OnOff" + Option "Follow player", "am_followplayer", "OnOff" StaticText " " Option "Show item counts", "am_showitems", "OnOff" Option "Show monster counts", "am_showmonsters", "OnOff" @@ -858,6 +866,7 @@ OptionMenu AutomapOptions Option "Show time elapsed", "am_showtime", "OnOff" Option "Show total time elapsed", "am_showtotaltime", "OnOff" Option "Show secrets on map", "am_map_secrets", "SecretTypes" + Option "Show map label", "am_showmaplabel", "MaplabelTypes" Option "Draw map background", "am_drawmapback", "OnOff" Option "Show keys (cheat)", "am_showkeys", "OnOff" } From 9493ea1d6bcb0b0a52805e5df842c02ff51c944f Mon Sep 17 00:00:00 2001 From: gez Date: Mon, 25 Oct 2010 12:41:41 +0000 Subject: [PATCH 08/82] * Updated to ZDoom r2967: - Fixed: Controller buttons were still translated to menu buttons when the controls menu was waiting for a button press, making it impossible to bind buttons that have special meaning to the menu from the menu. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1066 b0f79afe-0144-0410-b225-9a4edf0717df --- src/menu/menu.cpp | 2 +- src/svnrevision.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index b4e64b6a..0bdc622f 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -544,7 +544,7 @@ bool M_Responder (event_t *ev) } } } - else if (ev->type == EV_KeyDown || ev->type == EV_KeyUp) + else if (menuactive != MENU_WaitKey && (ev->type == EV_KeyDown || ev->type == EV_KeyUp)) { keyup = ev->type == EV_KeyUp; diff --git a/src/svnrevision.h b/src/svnrevision.h index b27410f0..7dd98cca 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2965" -#define ZD_SVN_REVISION_NUMBER 2965 +#define ZD_SVN_REVISION_STRING "2967" +#define ZD_SVN_REVISION_NUMBER 2967 From bd3b29e6133a74e8b3b866a58baa979a81942700 Mon Sep 17 00:00:00 2001 From: gez Date: Sat, 30 Oct 2010 08:52:07 +0000 Subject: [PATCH 09/82] * Updated to ZDoom r2968: - Fixed: The cast call could not handle actors with changing sprites - Fixed: The cast call was missing some NULL pointer checks for invalid actor classes. - Fixed: The cast call did not use a translation defined for an actor class. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1067 b0f79afe-0144-0410-b225-9a4edf0717df --- src/intermission/intermission.cpp | 62 +++++++++++++++++++++---------- src/intermission/intermission.h | 1 - src/svnrevision.h | 4 +- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index f22df89f..0b8afa1e 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -392,7 +392,12 @@ void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first) mName = static_cast(desc)->mName; mClass = PClass::FindClass(static_cast(desc)->mCastClass); if (mClass != NULL) mDefaults = GetDefaultByType(mClass); - else mDefaults = NULL; + else + { + mDefaults = NULL; + caststate = NULL; + return; + } mCastSounds.Resize(static_cast(desc)->mCastSounds.Size()); for (unsigned i=0; i < mCastSounds.Size(); i++) @@ -405,15 +410,17 @@ void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first) if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn))) { advplayerstate = mDefaults->MissileState; - castsprite = skins[players[consoleplayer].userinfo.skin].sprite; casttranslation = translationtables[TRANSLATION_Players][consoleplayer]; } else { advplayerstate = NULL; - if (caststate != NULL) castsprite = caststate->sprite; - else castsprite = -1; casttranslation = NULL; + if (mDefaults->Translation != 0) + { + casttranslation = translationtables[GetTranslationType(mDefaults->Translation)] + [GetTranslationIndex(mDefaults->Translation)]; + } } castdeath = false; castframes = 0; @@ -434,22 +441,25 @@ int DIntermissionScreenCast::Responder (event_t *ev) castdeath = true; - FName label[] = {NAME_Death, NAME_Cast}; - caststate = mClass->ActorInfo->FindState(2, label); - if (caststate == NULL) return -1; - - casttics = caststate->GetTics(); - castframes = 0; - castattacking = false; - - if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn))) + if (mClass != NULL) { - int snd = S_FindSkinnedSound(players[consoleplayer].mo, "*death"); - if (snd != 0) S_Sound (CHAN_VOICE | CHAN_UI, snd, 1, ATTN_NONE); - } - else if (mDefaults->DeathSound) - { - S_Sound (CHAN_VOICE | CHAN_UI, mDefaults->DeathSound, 1, ATTN_NONE); + FName label[] = {NAME_Death, NAME_Cast}; + caststate = mClass->ActorInfo->FindState(2, label); + if (caststate == NULL) return -1; + + casttics = caststate->GetTics(); + castframes = 0; + castattacking = false; + + if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn))) + { + int snd = S_FindSkinnedSound(players[consoleplayer].mo, "*death"); + if (snd != 0) S_Sound (CHAN_VOICE | CHAN_UI, snd, 1, ATTN_NONE); + } + else if (mDefaults->DeathSound) + { + S_Sound (CHAN_VOICE | CHAN_UI, mDefaults->DeathSound, 1, ATTN_NONE); + } } return true; } @@ -562,6 +572,20 @@ void DIntermissionScreenCast::Drawer () // draw the current frame in the middle of the screen if (caststate != NULL) { + int castsprite; + + if (!(mDefaults->flags4 & MF4_NOSKIN) && + mDefaults->SpawnState != NULL && caststate->sprite == mDefaults->SpawnState->sprite && + mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)) && + skins != NULL) + { + castsprite = skins[players[consoleplayer].userinfo.skin].sprite; + } + else + { + castsprite = caststate->sprite; + } + sprframe = &SpriteFrames[sprites[castsprite].spriteframes + caststate->GetFrame()]; pic = TexMan(sprframe->Texture[0]); diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index 4298b54b..1035bd8f 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -234,7 +234,6 @@ class DIntermissionScreenCast : public DIntermissionScreen TArray mCastSounds; int casttics; - int castsprite; // [RH] For overriding the player sprite with a skin const FRemapTable *casttranslation; // [RH] Draw "our hero" with their chosen suit color FState* caststate; FState* basestate; diff --git a/src/svnrevision.h b/src/svnrevision.h index 7dd98cca..0ab5ae13 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2967" -#define ZD_SVN_REVISION_NUMBER 2967 +#define ZD_SVN_REVISION_STRING "2968" +#define ZD_SVN_REVISION_NUMBER 2968 From f099b670a163450a8a12752b74a7297ad83ad1e8 Mon Sep 17 00:00:00 2001 From: gez Date: Wed, 3 Nov 2010 09:06:26 +0000 Subject: [PATCH 10/82] * Updated to ZDoom r2975: - Added a new AmbientSoundNoGravity actor with doomednum 14067. This is identical in every respect to the existing AmbientSound actor, except it also has the NOGRAVITY flag set. - Fixed: Pressing left or right on a video mode option line should play "menu/cursor", not "menu/change". - Modify AimingCamera so that it can pick up targets after spawning, since this is the only way for it to aim at players, who cannot be spawned with TIDs. - Fixed: Options selected in Strife dialogues using the number keys were off by one. - Fixed: The minimum velocity for player landing in effects in P_ZMovement should be -8, not -9. - Revised usage of jumpTics. In Hexen, it went like this: * When you jump, it gets set to 18. * When you land, it gets set to 7. * As long as it is non-zero, it counts down, and you cannot jump. Of note here, is that setting it to 18 upon jumping seems useless, since you can't jump unless you're on the ground, and when you reach the ground, it will always be set to 7. With that in mind, the new behavior is: * When you jump, it gets set to -1. * When you land, if it is less than zero or you fall far enough to squat, jumpTics will be set to 7. Otherwise, jumpTics is left alone. * If jumpTics is positive, it will count down each tic. * As long as JumpTics is non-zero, you cannot jump. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1069 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_shared/a_camera.cpp | 11 ++++++++++- src/menu/optionmenuitems.h | 4 ++-- src/p_conversation.cpp | 2 +- src/p_mobj.cpp | 4 ++-- src/p_user.cpp | 8 ++++---- src/svnrevision.h | 4 ++-- wadsrc/static/actors/shared/soundsequence.txt | 5 +++++ 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/g_shared/a_camera.cpp b/src/g_shared/a_camera.cpp index 99da16ae..c75ccbe8 100644 --- a/src/g_shared/a_camera.cpp +++ b/src/g_shared/a_camera.cpp @@ -143,12 +143,21 @@ void AAimingCamera::PostBeginPlay () tracer = iterator.Next (); if (tracer == NULL) { - Printf ("AimingCamera %d: Can't find thing %d\n", tid, args[3]); + //Printf ("AimingCamera %d: Can't find TID %d\n", tid, args[3]); + } + else + { // Don't try for a new target upon losing this one. + args[3] = 0; } } void AAimingCamera::Tick () { + if (tracer == NULL && args[3] != 0) + { // Recheck, in case something with this TID was created since the last time. + TActorIterator iterator (args[3]); + tracer = iterator.Next (); + } if (tracer != NULL) { angle_t delta; diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index e365f603..8aab6f9c 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -891,13 +891,13 @@ public: if (mkey == MKEY_Left) { if (--mSelection < 0) mSelection = mMaxValid; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); return true; } else if (mkey == MKEY_Right) { if (++mSelection > mMaxValid) mSelection = 0; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); return true; } else diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 3c631c4e..9b1119e0 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -914,7 +914,7 @@ public: { if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_Char && ev->data1 >= '0' && ev->data1 <= '9') { // Activate an item of type numberedmore (dialogue only) - mSelection = ev->data1 == '0' ? 10 : ev->data1 - '0'; + mSelection = ev->data1 == '0' ? 9 : ev->data1 - '1'; return MenuEvent(MKEY_Enter, false); } return Super::Responder(ev); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 71e0a251..1d6e8d40 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2237,7 +2237,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) mo->z = mo->floorz; if (mo->velz < 0) { - const fixed_t minvel = -9*FRACUNIT; // landing speed from a jump with normal gravity + const fixed_t minvel = -8*FRACUNIT; // landing speed from a jump with normal gravity // Spawn splashes, etc. P_HitFloor (mo); @@ -2253,7 +2253,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) mo->HitFloor (); if (mo->player) { - if (mo->player->jumpTics != 0 && mo->velz < -grav*4) + if (mo->player->jumpTics < 0 || mo->velz < minvel) { // delay any jumping for a short while mo->player->jumpTics = 7; } diff --git a/src/p_user.cpp b/src/p_user.cpp index e844d268..f80ddb9a 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2156,7 +2156,7 @@ void P_PlayerThink (player_t *player) P_DeathThink (player); return; } - if (player->jumpTics) + if (player->jumpTics > 0) { player->jumpTics--; } @@ -2217,7 +2217,7 @@ void P_PlayerThink (player_t *player) // [RH] check for jump if (cmd->ucmd.buttons & BT_JUMP) { - if (player->crouchoffset!=0) + if (player->crouchoffset != 0) { // Jumping while crouching will force an un-crouch but not jump player->crouching = 1; @@ -2231,7 +2231,7 @@ void P_PlayerThink (player_t *player) { player->mo->velz = 3*FRACUNIT; } - else if (level.IsJumpingAllowed() && onground && !player->jumpTics) + else if (level.IsJumpingAllowed() && onground && player->jumpTics == 0) { fixed_t jumpvelz = player->mo->JumpZ * 35 / TICRATE; @@ -2241,7 +2241,7 @@ void P_PlayerThink (player_t *player) player->mo->velz += jumpvelz; S_Sound (player->mo, CHAN_BODY, "*jump", 1, ATTN_NORM); player->mo->flags2 &= ~MF2_ONMOBJ; - player->jumpTics = 18*TICRATE/35; + player->jumpTics = -1; } } diff --git a/src/svnrevision.h b/src/svnrevision.h index 0ab5ae13..d39a5f54 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2968" -#define ZD_SVN_REVISION_NUMBER 2968 +#define ZD_SVN_REVISION_STRING "2975" +#define ZD_SVN_REVISION_NUMBER 2975 diff --git a/wadsrc/static/actors/shared/soundsequence.txt b/wadsrc/static/actors/shared/soundsequence.txt index 871bd724..ff240ba9 100644 --- a/wadsrc/static/actors/shared/soundsequence.txt +++ b/wadsrc/static/actors/shared/soundsequence.txt @@ -6,6 +6,11 @@ ACTOR AmbientSound 14065 native +DONTSPLASH } +ACTOR AmbientSoundNoGravity : AmbientSound 14067 +{ + +NOGRAVITY +} + ACTOR SoundSequenceSlot native { +NOSECTOR From 0dd982ce41d7955cda77d618bb0792f2fb9b2152 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 4 Nov 2010 07:53:18 +0000 Subject: [PATCH 11/82] Update to ZDoom r2980: * Use the so-called SafeTerminateProcess() function to kill the child TiMidity++ process instead of signaling an event. I would have preferred to use GenerateConsoleCtrlEvent(), but since it requires the caller be attached to the same console as the process it wants to kill, it's pretty much worthless. We will continue to look for the presence of the event name in the TiMidity++ binary despite no longer using it, because standard TiMidity++ builds do not write to stdout in binary mode on Windows systems. * Tweaked jumpTics again. As before, it now counts down whenever it is non-zero. If the player is on the ground and it counts below -18, it is zeroed so that the player can jump again. This handles cases where either the player did not actually jump when they pressed +jump (because there was a ceiling in the way) or when they land on something other than the floor. * Fixed: With the Buddha cheat active the health of the real player actor was not synchronized with the player data if a voodoo doll received damage that would have killed it. * Fixed: The message for trying to quickload in netgames used the wrong display mode for the message menu. * Fixed: AdjustPusher compared a sector's index with a tag to check for existing pushers in that sector. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1070 b0f79afe-0144-0410-b225-9a4edf0717df --- src/menu/messagebox.cpp | 2 +- src/p_interaction.cpp | 3 +- src/p_lnspec.cpp | 2 +- src/p_user.cpp | 6 ++- src/sound/i_musicinterns.h | 1 - src/sound/music_midi_timidity.cpp | 89 ++++++++++++++++++++++++------- 6 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index eecd997e..e415f57c 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -679,7 +679,7 @@ CCMD (quickload) if (netgame) { - M_StartMessage (GStrings("QLOADNET"), NULL); + M_StartMessage (GStrings("QLOADNET"), 1); return; } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 93bb0c44..4a082cff 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1164,7 +1164,8 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage // but telefragging should still do enough damage to kill the player) if ((player->cheats & CF_BUDDHA) && damage < TELEFRAG_DAMAGE) { - target->health = player->health = 1; + // If this is a voodoo doll we need to handle the real player as well. + player->mo->health = target->health = player->health = 1; } else { diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index d71bfbf7..a7f799c8 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1897,7 +1897,7 @@ void AdjustPusher (int tag, int magnitude, int angle, DPusher::EPusher type) unsigned int i; for (i = 0; i < numcollected; i++) { - if (Collection[i].RefNum == sectors[secnum].tag) + if (Collection[i].RefNum == sectors[secnum].sectornum) break; } if (i == numcollected) diff --git a/src/p_user.cpp b/src/p_user.cpp index f80ddb9a..836b665d 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2156,9 +2156,13 @@ void P_PlayerThink (player_t *player) P_DeathThink (player); return; } - if (player->jumpTics > 0) + if (player->jumpTics != 0) { player->jumpTics--; + if (onground && player->jumpTics < -18) + { + player->jumpTics = 0; + } } if (player->morphTics && !(player->cheats & CF_PREDICTING)) { diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 29b655d1..4ce8a7b0 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -202,7 +202,6 @@ protected: #ifdef _WIN32 HANDLE ReadWavePipe; HANDLE WriteWavePipe; - HANDLE KillerEvent; HANDLE ChildProcess; bool Validated; bool ValidateTimidity(); diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index dcaa934b..bb897bef 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -20,8 +20,10 @@ void ChildSigHandler (int signum) #endif #ifdef _WIN32 -const char TimidityPPMIDIDevice::EventName[] = "TiMidity Killer"; +BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode); + static char TimidityTitle[] = "TiMidity (ZDoom Launched)"; +const char TimidityPPMIDIDevice::EventName[] = "TiMidity Killer"; CVAR (String, timidity_exe, "timidity.exe", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) #else @@ -71,7 +73,6 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice() : DiskName("zmid"), #ifdef _WIN32 ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE), - KillerEvent(INVALID_HANDLE_VALUE), ChildProcess(INVALID_HANDLE_VALUE), Validated(false) #else @@ -108,11 +109,6 @@ TimidityPPMIDIDevice::~TimidityPPMIDIDevice () CloseHandle (ReadWavePipe); ReadWavePipe = INVALID_HANDLE_VALUE; } - if (KillerEvent != INVALID_HANDLE_VALUE) - { - CloseHandle (KillerEvent); - KillerEvent = INVALID_HANDLE_VALUE; - } #else if (WavePipe[1] != -1) { @@ -186,12 +182,6 @@ int TimidityPPMIDIDevice::Open(void (*callback)(unsigned int, void *, DWORD, DWO } Validated = true; - KillerEvent = CreateEvent(NULL, FALSE, FALSE, EventName); - if (KillerEvent == INVALID_HANDLE_VALUE) - { - Printf(PRINT_BOLD, "Could not create TiMidity++ kill event.\n"); - return 102; - } #endif // WIN32 CommandLine.Format("%s %s -EFchorus=%s -EFreverb=%s -s%d ", @@ -398,11 +388,11 @@ bool TimidityPPMIDIDevice::LaunchTimidity () startup.wShowWindow = SW_SHOWMINNOACTIVE; if (CreateProcess(NULL, CommandLine.LockBuffer(), NULL, NULL, TRUE, - /*HIGH_PRIORITY_CLASS|*/DETACHED_PROCESS, NULL, NULL, &startup, &procInfo)) + DETACHED_PROCESS, NULL, NULL, &startup, &procInfo)) { ChildProcess = procInfo.hProcess; //SetThreadPriority (procInfo.hThread, THREAD_PRIORITY_HIGHEST); - CloseHandle (procInfo.hThread); // Don't care about the created thread + CloseHandle(procInfo.hThread); // Don't care about the created thread CommandLine.UnlockBuffer(); return true; } @@ -647,10 +637,8 @@ void TimidityPPMIDIDevice::Stop () #ifdef _WIN32 if (ChildProcess != INVALID_HANDLE_VALUE) { - SetEvent(KillerEvent); - if (WaitForSingleObject(ChildProcess, 500) != WAIT_OBJECT_0) + if (!SafeTerminateProcess(ChildProcess, 666) && GetLastError() != ERROR_PROCESS_ABORTED) { - ResetEvent(KillerEvent); TerminateProcess(ChildProcess, 666); } CloseHandle(ChildProcess); @@ -670,3 +658,68 @@ void TimidityPPMIDIDevice::Stop () } Started = false; } + +#ifdef _WIN32 +/* + Safely terminate a process by creating a remote thread + in the process that calls ExitProcess + + Source is a Dr Dobbs article circa 1999. +*/ +typedef HANDLE (WINAPI *CreateRemoteThreadProto)(HANDLE,LPSECURITY_ATTRIBUTES,SIZE_T,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD); + +BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode) +{ + DWORD dwTID, dwCode; + HRESULT dwErr = 0; + HANDLE hRT = NULL; + HINSTANCE hKernel = GetModuleHandle("Kernel32"); + BOOL bSuccess = FALSE; + + // Detect the special case where the process is already dead... + if ( GetExitCodeProcess(hProcess, &dwCode) && (dwCode == STILL_ACTIVE) ) + { + FARPROC pfnExitProc; + CreateRemoteThreadProto pfCreateRemoteThread; + + pfnExitProc = GetProcAddress(hKernel, "ExitProcess"); + + // CreateRemoteThread does not exist on 9x systems. + pfCreateRemoteThread = (CreateRemoteThreadProto)GetProcAddress(hKernel, "CreateRemoteThread"); + + if (pfCreateRemoteThread == NULL) + { + dwErr = ERROR_INVALID_FUNCTION; + } + else + { + hRT = pfCreateRemoteThread(hProcess, + NULL, + 0, + (LPTHREAD_START_ROUTINE)pfnExitProc, + (PVOID)(UINT_PTR)uExitCode, 0, &dwTID); + + if ( hRT == NULL ) + dwErr = GetLastError(); + } + } + else + { + dwErr = ERROR_PROCESS_ABORTED; + } + + if ( hRT ) + { + // Must wait process to terminate to guarantee that it has exited... + WaitForSingleObject(hProcess, INFINITE); + + CloseHandle(hRT); + bSuccess = TRUE; + } + + if ( !bSuccess ) + SetLastError(dwErr); + + return bSuccess; +} +#endif From 88c45d187de79c4c8bab9e7fe040c84c9139e70a Mon Sep 17 00:00:00 2001 From: gez Date: Sat, 6 Nov 2010 18:20:08 +0000 Subject: [PATCH 12/82] * Updated to ZDoom r2981: - Added some initial configurability to statistics intermission screen: * Font and color for map name can be set if it's not a titlepatch * 'Finished' and 'Entering' can be either patches or a printed text in all gamees now. * Font and color for 'finished' and 'entering' text can be set. * Moved 'finished' and 'Now entering:' texts into string table. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1071 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_level.cpp | 7 +- src/gi.cpp | 27 ++++ src/gi.h | 9 ++ src/svnrevision.h | 4 +- src/wi_stuff.cpp | 190 +++++++++++++++------------ wadsrc/static/language.enu | 3 + wadsrc/static/mapinfo/chex.txt | 3 + wadsrc/static/mapinfo/doomcommon.txt | 3 + wadsrc/static/mapinfo/heretic.txt | 3 + wadsrc/static/mapinfo/hexen.txt | 3 + wadsrc/static/mapinfo/strife.txt | 3 + 11 files changed, 164 insertions(+), 91 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 7008572a..e3321f88 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -742,12 +742,7 @@ void G_DoCompleted (void) { // Reset world variables for the new hub. P_ClearACSVars(false); } - // With hub statistics the time should be per hub. - // Additionally there is a global time counter now so nothing is missed by changing it - //else if (mode == FINISH_NoHub) - { // Reset time to zero if not entering/staying in a hub. - level.time = 0; - } + level.time = 0; level.maptime = 0; } diff --git a/src/gi.cpp b/src/gi.cpp index 4dfac16f..705f9b80 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -163,6 +163,28 @@ const char* GameInfoBoarders[] = } \ } +#define GAMEINFOKEY_FONT(key, variable) \ + else if(nextKey.CompareNoCase(variable) == 0) \ + { \ + sc.MustGetToken(TK_StringConst); \ + gameinfo.key.fontname = sc.String; \ + if (sc.CheckToken(',')) { \ + sc.MustGetToken(TK_StringConst); \ + gameinfo.key.color = sc.String; \ + } else { \ + gameinfo.key.color = NAME_None; \ + } \ + } + +#define GAMEINFOKEY_PATCH(key, variable) \ + else if(nextKey.CompareNoCase(variable) == 0) \ + { \ + sc.MustGetToken(TK_StringConst); \ + gameinfo.key.fontname = sc.String; \ + gameinfo.key.color = NAME_Null; \ + } + + void FMapInfoParser::ParseGameInfo() { sc.MustGetToken('{'); @@ -311,6 +333,11 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_INT(TextScreenX, "textscreenx") GAMEINFOKEY_INT(TextScreenY, "textscreeny") GAMEINFOKEY_STRING(DefaultEndSequence, "defaultendsequence") + GAMEINFOKEY_FONT(mStatscreenMapNameFont, "statscreen_mapnamefont") + GAMEINFOKEY_FONT(mStatscreenFinishedFont, "statscreen_finishedfont") + GAMEINFOKEY_FONT(mStatscreenEnteringFont, "statscreen_enteringfont") + GAMEINFOKEY_PATCH(mStatscreenFinishedFont, "statscreen_finishedpatch") + GAMEINFOKEY_PATCH(mStatscreenEnteringFont, "statscreen_enteringpatch") else { diff --git a/src/gi.h b/src/gi.h index d9422c03..42405262 100644 --- a/src/gi.h +++ b/src/gi.h @@ -66,6 +66,12 @@ struct gameborder_t char br[8]; }; +struct FGIFont +{ + FName fontname; + FName color; +}; + struct gameinfo_t { int flags; @@ -130,6 +136,9 @@ struct gameinfo_t int TextScreenY; FName DefaultEndSequence; FString mMapArrow, mCheatMapArrow; + FGIFont mStatscreenMapNameFont; + FGIFont mStatscreenFinishedFont; + FGIFont mStatscreenEnteringFont; const char *GetFinalePage(unsigned int num) const; }; diff --git a/src/svnrevision.h b/src/svnrevision.h index d39a5f54..fa451fc8 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2975" -#define ZD_SVN_REVISION_NUMBER 2975 +#define ZD_SVN_REVISION_STRING "2981" +#define ZD_SVN_REVISION_NUMBER 2981 diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 42291681..dbf8446a 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -47,6 +47,7 @@ #include "gi.h" #include "r_translate.h" #include "templates.h" +#include "gstrings.h" // States for the intermission typedef enum @@ -206,10 +207,39 @@ static bool noautostartmap; // GRAPHICS // +struct FPatchInfo +{ + FFont *mFont; + FTexture *mPatch; + EColorRange mColor; + + void Init(FGIFont &gifont) + { + if (gifont.color == NAME_Null) + { + mPatch = TexMan[gifont.fontname]; // "entering" + mColor = mPatch == NULL? CR_UNTRANSLATED : CR_UNDEFINED; + mFont = NULL; + } + else + { + mFont = V_GetFont(gifont.fontname); + mColor = V_FindFontColor(gifont.color); + mPatch = NULL; + } + if (mFont == NULL) + { + mFont = BigFont; + } + } +}; + +static FPatchInfo mapname; +static FPatchInfo finished; +static FPatchInfo entering; + static TArray yah; // You Are Here graphic static FTexture* splat; // splat -static FTexture* finished; // "Finished!" graphics -static FTexture* entering; // "Entering" graphic static FTexture* sp_secret; // "secret" static FTexture* kills; // "Kills", "Scrt", "Items", "Frags" static FTexture* secret; @@ -697,34 +727,67 @@ static int WI_DrawCharPatch (FFont *font, int charcode, int x, int y, EColorRang // //==================================================================== -int WI_DrawName(int y, const char *levelname) +int WI_DrawName(int y, FTexture *tex, const char *levelname) { - int i; - size_t l; - const char *p; - int h = 0; - int lumph; - - lumph = BigFont->GetHeight() * CleanYfac; - - p = levelname; - if (!p) return 0; - l = strlen(p); - if (!l) return 0; - - FBrokenLines *lines = V_BreakLines(BigFont, screen->GetWidth() / CleanXfac, p); - - if (lines) + // draw + if (tex) { - for (i = 0; lines[i].Width >= 0; i++) - { - screen->DrawText(BigFont, CR_UNTRANSLATED, (SCREENWIDTH - lines[i].Width * CleanXfac) / 2, y + h, - lines[i].Text, DTA_CleanNoMove, true, TAG_DONE); - h += lumph; - } - V_FreeBrokenLines(lines); + screen->DrawTexture(tex, (screen->GetWidth() - tex->GetScaledWidth()*CleanXfac) /2, y, DTA_CleanNoMove, true, TAG_DONE); + return y + (tex->GetScaledHeight() + BigFont->GetHeight()/4) * CleanYfac; + } + else + { + int i; + size_t l; + const char *p; + int h = 0; + int lumph; + + lumph = mapname.mFont->GetHeight() * CleanYfac; + + p = levelname; + if (!p) return 0; + l = strlen(p); + if (!l) return 0; + + FBrokenLines *lines = V_BreakLines(mapname.mFont, screen->GetWidth() / CleanXfac, p); + + if (lines) + { + for (i = 0; lines[i].Width >= 0; i++) + { + screen->DrawText(mapname.mFont, mapname.mColor, (SCREENWIDTH - lines[i].Width * CleanXfac) / 2, y + h, + lines[i].Text, DTA_CleanNoMove, true, TAG_DONE); + h += lumph; + } + V_FreeBrokenLines(lines); + } + return y + h + lumph/4; + } +} + +//==================================================================== +// +// Draws a text, either as patch or as string from the string table +// +//==================================================================== + +int WI_DrawPatchText(int y, FPatchInfo *pinfo, const char *stringname) +{ + const char *string = GStrings(stringname); + int midx = screen->GetWidth() / 2; + + if (pinfo->mPatch != NULL) + { + screen->DrawTexture(pinfo->mPatch, midx - pinfo->mPatch->GetScaledWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE); + return y + (pinfo->mPatch->GetScaledHeight() * CleanYfac); + } + else + { + screen->DrawText(pinfo->mFont, pinfo->mColor, midx - pinfo->mFont->StringWidth(string)*CleanXfac/2, + y, string, DTA_CleanNoMove, true, TAG_DONE); + return y + pinfo->mFont->GetHeight() * CleanYfac; } - return h + lumph/4; } @@ -736,41 +799,21 @@ int WI_DrawName(int y, const char *levelname) // A level name patch can be specified for all games now, not just Doom. // //==================================================================== + int WI_drawLF () { int y = WI_TITLEY * CleanYfac; - int midx = screen->GetWidth() / 2; - FTexture *tex = wbs->LName0; - - // draw - if (tex) - { - screen->DrawTexture(tex, midx - tex->GetScaledWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE); - y += (tex->GetScaledHeight() + BigFont->GetHeight()/4) * CleanYfac; - } - else - { - y += WI_DrawName(y, lnametexts[0]); - } + y = WI_DrawName(y, wbs->LName0, lnametexts[0]); + // Adjustment for different font sizes for map name and 'finished'. + y -= ((mapname.mFont->GetHeight() - finished.mFont->GetHeight()) * CleanYfac) / 4; + // draw "Finished!" - FFont *font = gameinfo.gametype & GAME_Raven ? SmallFont : BigFont; - if (y < (NG_STATSY - font->GetHeight()*3/4) * CleanYfac) + if (y < (NG_STATSY - finished.mFont->GetHeight()*3/4) * CleanYfac) { - // don't draw 'finished' if the level name is too high! - if (gameinfo.gametype & GAME_DoomChex) - { - screen->DrawTexture(finished, midx - finished->GetScaledWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE); - return y + finished->GetScaledHeight() * CleanYfac; - } - else - { - screen->DrawText(font, CR_WHITE, - midx - font->StringWidth("finished")*CleanXfac/2, y - 4*CleanYfac, "finished", - DTA_CleanNoMove, true, TAG_DONE); - return y + font->GetHeight() * CleanYfac; - } + // don't draw 'finished' if the level name is too tall + y = WI_DrawPatchText(y, &finished, "WI_FINISHED"); } return y; } @@ -784,36 +827,14 @@ int WI_drawLF () // A level name patch can be specified for all games now, not just Doom. // //==================================================================== + void WI_drawEL () { int y = WI_TITLEY * CleanYfac; - FFont *font = gameinfo.gametype & GAME_Raven ? SmallFont : BigFont; - // draw "entering" - // be careful with the added height so that it works for oversized 'entering' patches! - if (gameinfo.gametype & GAME_DoomChex) - { - screen->DrawTexture(entering, (SCREENWIDTH - entering->GetScaledWidth() * CleanXfac) / 2, y, DTA_CleanNoMove, true, TAG_DONE); - y += (entering->GetScaledHeight() + font->GetHeight()/4) * CleanYfac; - } - else - { - screen->DrawText(font, CR_WHITE, - (SCREENWIDTH - font->StringWidth("now entering:") * CleanXfac) / 2, y, - "now entering:", DTA_CleanNoMove, true, TAG_DONE); - y += font->GetHeight()*5*CleanYfac/4; - } - - // draw - FTexture *tex = wbs->LName1; - if (tex) - { - screen->DrawTexture(tex, (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac) / 2, y, DTA_CleanNoMove, true, TAG_DONE); - } - else - { - WI_DrawName(y, lnametexts[1]); - } + y = WI_DrawPatchText(y, &entering, "WI_ENTERING"); + y += entering.mFont->GetHeight() * CleanYfac / 4; + WI_DrawName(y, wbs->LName1, lnametexts[1]); } @@ -1905,12 +1926,15 @@ void WI_Ticker(void) } } + void WI_loadData(void) { + entering.Init(gameinfo.mStatscreenEnteringFont); + finished.Init(gameinfo.mStatscreenFinishedFont); + mapname.Init(gameinfo.mStatscreenMapNameFont); + if (gameinfo.gametype & GAME_DoomChex) { - finished = TexMan["WIF"]; // "finished" - entering = TexMan["WIENTER"]; // "entering" kills = TexMan["WIOSTK"]; // "kills" secret = TexMan["WIOSTS"]; // "scrt" sp_secret = TexMan["WISCRT2"]; // "secret" diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index f3fb2bce..1a222f1f 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1563,6 +1563,9 @@ $ifgame(heretic) SWSTRING = "ONLY AVAILABLE IN THE REGISTERED VERSION"; MNU_EPISODE = "Select Episode"; +WI_FINISHED = "finished"; +WI_ENTERING = "Now entering:"; + // Bloodbath announcer BBA_BONED = "%k boned %o like a fish"; diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index 79f27f5b..acc4462b 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -61,6 +61,9 @@ gameinfo textscreeny = 10 defaultendsequence = "Inter_Pic1" maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt" + statscreen_mapnamefont = "BigFont" + statscreen_finishedpatch = "WIF" + statscreen_enteringpatch = "WIENTER" } skill baby diff --git a/wadsrc/static/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt index 73d00379..f152aa73 100644 --- a/wadsrc/static/mapinfo/doomcommon.txt +++ b/wadsrc/static/mapinfo/doomcommon.txt @@ -62,6 +62,9 @@ gameinfo textscreeny = 10 defaultendsequence = "Inter_Cast" maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt" + statscreen_mapnamefont = "BigFont" + statscreen_finishedpatch = "WIF" + statscreen_enteringpatch = "WIENTER" } skill baby diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 57aa839f..33ab5819 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -61,6 +61,9 @@ gameinfo textscreeny = 5 defaultendsequence = "Inter_Pic1" maparrow = "maparrows/dagger.txt" + statscreen_mapnamefont = "BigFont" + statscreen_finishedfont = "SmallFont" + statscreen_enteringfont = "SmallFont" } skill baby diff --git a/wadsrc/static/mapinfo/hexen.txt b/wadsrc/static/mapinfo/hexen.txt index eeef3b92..83202485 100644 --- a/wadsrc/static/mapinfo/hexen.txt +++ b/wadsrc/static/mapinfo/hexen.txt @@ -59,6 +59,9 @@ gameinfo textscreeny = 5 defaultendsequence = "Inter_Chess" maparrow = "maparrows/dagger.txt" + statscreen_mapnamefont = "BigFont" + statscreen_finishedfont = "SmallFont" + statscreen_enteringfont = "SmallFont" } skill baby diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index 2e6c242c..7791d736 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -61,6 +61,9 @@ gameinfo textscreeny = 10 defaultendsequence = "Inter_Strife" maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt" + statscreen_mapnamefont = "BigFont" + statscreen_finishedfont = "BigFont", "white" + statscreen_enteringfont = "BigFont", "white" } Intermission Inter_Strife_Good From 636f4a5de6a82069bb2d62ab6f0bf5015f7d28af Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 7 Nov 2010 05:28:55 +0000 Subject: [PATCH 13/82] * Updated to ZDoom r2983: - Fixed the value set of a few dmflags options. - Fixed: Ultimate Doom loaded the default MAPINFO for regular Doom 1. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1072 b0f79afe-0144-0410-b225-9a4edf0717df --- wadsrc/static/iwadinfo.txt | 2 +- wadsrc/static/menudef.txt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index 47001257..2bf5f836 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -216,7 +216,7 @@ IWad Autoname = "Doom1" Game = "Doom" Config = "Doom" - Mapinfo = "mapinfo/doom1.txt" + Mapinfo = "mapinfo/ultdoom.txt" Compatibility = "Shorttex" MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9", "E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9", diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 4a577d90..5097106e 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1103,12 +1103,12 @@ OptionMenu GameplayOptions StaticText "Deathmatch Settings",1 Option "Weapons stay", "sv_weaponstay", "YesNo" Option "Allow powerups", "sv_noitems", "NoYes" - Option "Allow health", "sv_nohealth", "YesNo" - Option "Allow armor", "sv_noarmor", "YesNo" + Option "Allow health", "sv_nohealth", "NoYes" + Option "Allow armor", "sv_noarmor", "NoYes" Option "Spawn farthest", "sv_spawnfarthest", "YesNo" Option "Same map", "sv_samelevel", "YesNo" Option "Force respawn", "sv_forcerespawn", "YesNo" - Option "Allow exit", "sv_noexit", "YesNo" + Option "Allow exit", "sv_noexit", "NoYes" Option "Barrels respawn", "sv_barrelrespawn", "YesNo" Option "Respawn protection", "sv_respawnprotect", "YesNo" Option "Lose frag if fragged", "sv_losefrag", "YesNo" From b95ad1be3ba24410524df6d996544421790c7c1c Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 7 Nov 2010 08:08:09 +0000 Subject: [PATCH 14/82] * Updated to ZDoom r2987: - Added Demolisher's APROP_Waterlevel patch. - Added TheShooter7's patch to use the PUFFGETSOWNER flag for blood, too. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1073 b0f79afe-0144-0410-b225-9a4edf0717df --- src/m_fixed.h | 1 + src/p_acs.cpp | 4 +++- src/p_mobj.cpp | 4 ++++ src/svnrevision.h | 4 ++-- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/m_fixed.h b/src/m_fixed.h index 14db59d6..61080d73 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -139,5 +139,6 @@ inline SDWORD ModDiv (SDWORD num, SDWORD den, SDWORD *dmval) #define FLOAT2FIXED(f) xs_Fix<16>::ToFix(f) #define FIXED2FLOAT(f) ((f) / float(65536)) +#define FIXED2DBL(f) ((f) / double(65536)) #endif diff --git a/src/p_acs.cpp b/src/p_acs.cpp index b789f22b..e7fff7d7 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2536,7 +2536,8 @@ enum APROP_DamageFactor = 24, APROP_MasterTID = 25, APROP_TargetTID = 26, - APROP_TracerTID = 27 + APROP_TracerTID = 27, + APROP_WaterLevel = 28 }; // These are needed for ACS's APROP_RenderStyle @@ -2778,6 +2779,7 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_MasterTID: return DoGetMasterTID (actor); case APROP_TargetTID: return (actor->target != NULL)? actor->target->tid : 0; case APROP_TracerTID: return (actor->tracer != NULL)? actor->tracer->tid : 0; + case APROP_WaterLevel: return actor->waterlevel; default: return 0; } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 1d6e8d40..79c20c1e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4526,6 +4526,8 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement th->velz = FRACUNIT*2; th->angle = dir; + // [NG] Applying PUFFGETSOWNER to the blood will make it target the owner + if (th->flags5 & MF5_PUFFGETSOWNER) th->target = originator; if (gameinfo.gametype & GAME_DoomChex) { th->tics -= pr_spawnblood() & 3; @@ -4667,6 +4669,8 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) { AActor *th; th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement + // [NG] Applying PUFFGETSOWNER to the blood will make it target the owner + if (th->flags5 & MF5_PUFFGETSOWNER) th->target = bleeder; if (gameinfo.gametype == GAME_Heretic) th->flags |= MF_NOGRAVITY; th->velx = mo->velx >> 1; diff --git a/src/svnrevision.h b/src/svnrevision.h index fa451fc8..ecc983ce 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2981" -#define ZD_SVN_REVISION_NUMBER 2981 +#define ZD_SVN_REVISION_STRING "2987" +#define ZD_SVN_REVISION_NUMBER 2987 From e0becf97db93094abff975536a793f25f4b7459f Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 7 Nov 2010 17:18:15 +0000 Subject: [PATCH 15/82] * Updated to ZDoom r2992: - Add alpha property to sector_t::splane. Not used yet. - Add an alpha parameter to R_FindPlane. - Fixed: R_FindPlane must do a full visplane comparison for stacked sectors with a non-0 alpha for the sector plane. - Made the alpha used by stacked sectors part of the visplane. This will be needed to fix the merging of stacks with the same displacement but different alpha values. - Replaced all calls to sqrtf with sqrt. Also changed P_RadiusAttack to use doubles for all floating point calculations. - Fixed: When playing non-looping songs GMESong::Read could return without releasing the critical section. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1074 b0f79afe-0144-0410-b225-9a4edf0717df --- src/am_map.cpp | 2 +- src/g_heretic/a_hereticweaps.cpp | 4 +-- src/g_shared/a_decals.cpp | 2 +- src/p_map.cpp | 36 +++++++++++++-------------- src/p_saveg.cpp | 8 ++++++ src/p_setup.cpp | 9 ++++--- src/r_bsp.cpp | 2 ++ src/r_defs.h | 11 +++++++++ src/r_plane.cpp | 42 +++++++++++++++++++------------- src/r_plane.h | 2 ++ src/sound/i_music.cpp | 2 -- src/sound/music_gme.cpp | 1 + src/svnrevision.h | 4 +-- 13 files changed, 78 insertions(+), 47 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 2de0a5bc..cf887615 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1533,7 +1533,7 @@ void AM_drawGrid (const AMColor &color) // [RH] Calculate a minimum for how long the grid lines should be so that // they cover the screen at any rotation. - minlen = (fixed_t)sqrtf ((float)m_w*(float)m_w + (float)m_h*(float)m_h); + minlen = (fixed_t)sqrt ((double)m_w*(double)m_w + (double)m_h*(double)m_h); extx = (minlen - m_w) / 2; exty = (minlen - m_h) / 2; diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index ad011508..0a44cdbe 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -462,8 +462,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check) self->velx = FixedMul(7*FRACUNIT, finecosine[angle]); self->vely = FixedMul(7*FRACUNIT, finesine[angle]); #else - double velscale = sqrtf ((float)self->velx * (float)self->velx + - (float)self->vely * (float)self->vely); + double velscale = sqrt ((double)self->velx * (double)self->velx + + (double)self->vely * (double)self->vely); velscale = 458752 / velscale; self->velx = (int)(self->velx * velscale); self->vely = (int)(self->vely * velscale); diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index d992bec9..1c15bd91 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -414,7 +414,7 @@ static void GetWallStuff (side_t *wall, vertex_t *&v1, fixed_t &ldx, fixed_t &ld static fixed_t Length (fixed_t dx, fixed_t dy) { - return (fixed_t)sqrtf ((float)dx*(float)dx+(float)dy*(float)dy); + return (fixed_t)sqrt ((double)dx*(double)dx+(double)dy*(double)dy); } static side_t *NextWall (const side_t *wall) diff --git a/src/p_map.cpp b/src/p_map.cpp index 3c791fea..082db59f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4305,8 +4305,8 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b return; fulldamagedistance = clamp(fulldamagedistance, 0, bombdistance-1); - float bombdistancefloat = 1.f / (float)(bombdistance - fulldamagedistance); - float bombdamagefloat = (float)bombdamage; + double bombdistancefloat = 1.f / (double)(bombdistance - fulldamagedistance); + double bombdamagefloat = (double)bombdamage; FVector3 bombvec(FIXED2FLOAT(bombspot->x), FIXED2FLOAT(bombspot->y), FIXED2FLOAT(bombspot->z)); @@ -4349,29 +4349,29 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b { // [RH] New code. The bounding box only covers the // height of the thing and not the height of the map. - float points; - float len; + double points; + double len; fixed_t dx, dy; - float boxradius; + double boxradius; dx = abs (thing->x - bombspot->x); dy = abs (thing->y - bombspot->y); - boxradius = float (thing->radius); + boxradius = double (thing->radius); // The damage pattern is square, not circular. - len = float (dx > dy ? dx : dy); + len = double (dx > dy ? dx : dy); if (bombspot->z < thing->z || bombspot->z >= thing->z + thing->height) { - float dz; + double dz; if (bombspot->z > thing->z) { - dz = float (bombspot->z - thing->z - thing->height); + dz = double (bombspot->z - thing->z - thing->height); } else { - dz = float (thing->z - bombspot->z); + dz = double (thing->z - bombspot->z); } if (len <= boxradius) { @@ -4380,7 +4380,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b else { len -= boxradius; - len = sqrtf (len*len + dz*dz); + len = sqrt (len*len + dz*dz); } } else @@ -4390,18 +4390,18 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b len = 0.f; } len /= FRACUNIT; - len = clamp(len - (float)fulldamagedistance, 0, len); + len = clamp(len - (double)fulldamagedistance, 0, len); points = bombdamagefloat * (1.f - len * bombdistancefloat); if (thing == bombsource) { points = points * splashfactor; } - points *= thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT)/(float)FRACUNIT; + points *= thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT)/(double)FRACUNIT; if (points > 0.f && P_CheckSight (thing, bombspot, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) { // OK to damage; target is in direct path - float velz; - float thrust; + double velz; + double thrust; int damage = (int)points; if (bombdodamage) P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); @@ -4415,12 +4415,12 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b { if (bombsource == NULL || !(bombsource->flags2 & MF2_NODMGTHRUST)) { - thrust = points * 0.5f / (float)thing->Mass; + thrust = points * 0.5f / (double)thing->Mass; if (bombsource == thing) { thrust *= selfthrustscale; } - velz = (float)(thing->z + (thing->height>>1) - bombspot->z) * thrust; + velz = (double)(thing->z + (thing->height>>1) - bombspot->z) * thrust; if (bombsource != thing) { velz *= 0.5f; @@ -4460,7 +4460,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b { // OK to damage; target is in direct path dist = clamp(dist - fulldamagedistance, 0, dist); int damage = Scale (bombdamage, bombdistance-dist, bombdistance); - damage = (int)((float)damage * splashfactor); + damage = (int)((double)damage * splashfactor); damage = Scale(damage, thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT), FRACUNIT); if (damage > 0) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 4be7243f..be842592 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -446,6 +446,14 @@ FArchive &operator<< (FArchive &arc, sector_t::splane &p) arc << p.xform.xoffs << p.xform.yoffs << p.xform.xscale << p.xform.yscale << p.xform.angle << p.xform.base_yoffs << p.xform.base_angle << p.Flags << p.Light << p.Texture << p.TexZ; + if (SaveVersion >= 2992) + { + arc << p.alpha; + } + else + { + p.alpha = FRACUNIT; + } return arc; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index b34b0cc2..f8233ce3 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1460,7 +1460,8 @@ void P_LoadSectors (MapData * map) ss->nextsec = -1; //jff 2/26/98 add fields to support locking out ss->prevsec = -1; // stair retriggering until build completes - // killough 3/7/98: + ss->SetAlpha(sector_t::ceiling, FRACUNIT); + ss->SetAlpha(sector_t::ceiling, FRACUNIT); ss->SetXScale(sector_t::floor, FRACUNIT); // [RH] floor and ceiling scaling ss->SetYScale(sector_t::floor, FRACUNIT); ss->SetXScale(sector_t::ceiling, FRACUNIT); @@ -1873,8 +1874,8 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha) ld->frontsector = ld->sidedef[0] != NULL ? ld->sidedef[0]->sector : NULL; ld->backsector = ld->sidedef[1] != NULL ? ld->sidedef[1]->sector : NULL; - float dx = FIXED2FLOAT(ld->v2->x - ld->v1->x); - float dy = FIXED2FLOAT(ld->v2->y - ld->v1->y); + double dx = FIXED2DBL(ld->v2->x - ld->v1->x); + double dy = FIXED2DBL(ld->v2->y - ld->v1->y); int linenum = int(ld-lines); if (ld->frontsector == NULL) @@ -1883,7 +1884,7 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha) } // [RH] Set some new sidedef properties - int len = (int)(sqrtf (dx*dx + dy*dy) + 0.5f); + int len = (int)(sqrt (dx*dx + dy*dy) + 0.5f); if (ld->sidedef[0] != NULL) { diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index e7ba7c11..e26b92ca 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -1197,6 +1197,7 @@ void R_Subsector (subsector_t *sub) R_FindPlane(frontsector->ceilingplane, // killough 3/8/98 frontsector->GetTexture(sector_t::ceiling), ceilinglightlevel + r_actualextralight, // killough 4/11/98 + frontsector->GetAlpha(sector_t::ceiling), frontsector->GetXOffset(sector_t::ceiling), // killough 3/7/98 frontsector->GetYOffset(sector_t::ceiling), // killough 3/7/98 frontsector->GetXScale(sector_t::ceiling), @@ -1221,6 +1222,7 @@ void R_Subsector (subsector_t *sub) R_FindPlane(frontsector->floorplane, frontsector->GetTexture(sector_t::floor), floorlightlevel + r_actualextralight, // killough 3/16/98 + frontsector->GetAlpha(sector_t::floor), frontsector->GetXOffset(sector_t::floor), // killough 3/7/98 frontsector->GetYOffset(sector_t::floor), // killough 3/7/98 frontsector->GetXScale(sector_t::floor), diff --git a/src/r_defs.h b/src/r_defs.h index be7117ca..d1ba877b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -476,6 +476,7 @@ struct sector_t FTransform xform; int Flags; int Light; + fixed_t alpha; FTextureID Texture; fixed_t TexZ; }; @@ -563,6 +564,16 @@ struct sector_t planes[pos].xform.base_angle = o; } + void SetAlpha(int pos, fixed_t o) + { + planes[pos].alpha = o; + } + + fixed_t GetAlpha(int pos) const + { + return planes[pos].alpha; + } + int GetFlags(int pos) const { return planes[pos].Flags; diff --git a/src/r_plane.cpp b/src/r_plane.cpp index cd0b9f4a..a5a40bc1 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -522,7 +522,7 @@ static visplane_t *new_visplane (unsigned hash) // killough 2/28/98: Add offsets //========================================================================== -visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightlevel, +visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightlevel, fixed_t alpha, fixed_t xoffs, fixed_t yoffs, fixed_t xscale, fixed_t yscale, angle_t angle, int sky, ASkyViewpoint *skybox) @@ -540,6 +540,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl xscale = 0; yscale = 0; angle = 0; + alpha = 0; plane.a = plane.b = plane.d = 0; // [RH] Map floor skies and ceiling skies to separate visplanes. This isn't // always necessary, but it is needed if a floor and ceiling sky are in the @@ -560,6 +561,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl plane = height; isskybox = false; sky = 0; // not skyflatnum so it can't be a sky + alpha = FRACUNIT; } // New visplane algorithm uses hash table -- killough @@ -579,6 +581,19 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl check->viewx == stacked_viewx && check->viewy == stacked_viewy && check->viewz == stacked_viewz && + check->alpha == alpha && + (alpha == 0 || // if alpha is > 0 everything needs to be checked + (plane == check->height && + picnum == check->picnum && + lightlevel == check->lightlevel && + xoffs == check->xoffs && // killough 2/28/98: Add offset checks + yoffs == check->yoffs && + basecolormap == check->colormap && // [RH] Add more checks + xscale == check->xscale && + yscale == check->yscale && + angle == check->angle + ) + ) && check->viewangle == stacked_angle) { return check; @@ -628,6 +643,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl check->viewy = stacked_viewy; check->viewz = stacked_viewz; check->viewangle = stacked_angle; + check->alpha = alpha; clearbufshort (check->top, viewwidth, 0x7fff); @@ -1034,26 +1050,19 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool masked) CVAR (Bool, r_skyboxes, true, 0) static int numskyboxes; -struct VisplaneAndAlpha -{ - visplane_t *Visplane; - fixed_t Alpha; -}; - void R_DrawSkyBoxes () { static TArray interestingStack; static TArray drawsegStack; static TArray visspriteStack; static TArray viewxStack, viewyStack, viewzStack; - static TArray visplaneStack; + static TArray visplaneStack; numskyboxes = 0; if (visplanes[MAXVISPLANES] == NULL) return; - VisplaneAndAlpha vaAdder = { 0 }; int savedextralight = extralight; fixed_t savedx = viewx; fixed_t savedy = viewy; @@ -1169,9 +1178,8 @@ void R_DrawSkyBoxes () viewxStack.Push (viewx); viewyStack.Push (viewy); viewzStack.Push (viewz); - vaAdder.Visplane = pl; - vaAdder.Alpha = sky->PlaneAlpha; - visplaneStack.Push (vaAdder); + pl->alpha = sky->PlaneAlpha; + visplaneStack.Push (pl); R_RenderBSPNode (nodes + numnodes - 1); R_DrawPlanes (); @@ -1200,13 +1208,13 @@ void R_DrawSkyBoxes () ds_p = firstdrawseg; vissprite_p = firstvissprite; - visplaneStack.Pop (vaAdder); - if (vaAdder.Alpha > 0) + visplaneStack.Pop (pl); + if (pl->alpha > 0) { - R_DrawSinglePlane (vaAdder.Visplane, vaAdder.Alpha, true); + R_DrawSinglePlane (pl, pl->alpha, true); } - *freehead = vaAdder.Visplane; - freehead = &vaAdder.Visplane->next; + *freehead = pl; + freehead = &pl->next; } firstvissprite = vissprites; vissprite_p = vissprites + savedvissprite_p; diff --git a/src/r_plane.h b/src/r_plane.h index 369083ba..2df6b1fd 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -54,6 +54,7 @@ struct visplane_s float visibility; fixed_t viewx, viewy, viewz; angle_t viewangle; + fixed_t alpha; unsigned short *bottom; // [RH] bottom and top arrays are dynamically unsigned short pad; // allocated immediately after the @@ -92,6 +93,7 @@ visplane_t *R_FindPlane ( const secplane_t &height, FTextureID picnum, int lightlevel, + fixed_t alpha, fixed_t xoffs, // killough 2/28/98: add x-y offsets fixed_t yoffs, fixed_t xscale, diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index ba98b470..0eedfbdc 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -477,8 +477,6 @@ MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int EMIDIType miditype = IdentifyMIDIType(id, sizeof(id)); if (miditype != MIDI_NOTMIDI) { - TArray midi; - EMidiDevice devtype = (EMidiDevice)device; retry_as_fmod: diff --git a/src/sound/music_gme.cpp b/src/sound/music_gme.cpp index 08700c8b..0c3d8c8c 100644 --- a/src/sound/music_gme.cpp +++ b/src/sound/music_gme.cpp @@ -349,6 +349,7 @@ bool GMESong::Read(SoundStream *stream, void *buff, int len, void *userdata) else { memset(buff, 0, len); + song->CritSec.Leave(); return false; } } diff --git a/src/svnrevision.h b/src/svnrevision.h index ecc983ce..ec45a847 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2987" -#define ZD_SVN_REVISION_NUMBER 2987 +#define ZD_SVN_REVISION_STRING "2992" +#define ZD_SVN_REVISION_NUMBER 2992 From d2f27f3fcb424bd593202aac8adba9a7c053a56b Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 7 Nov 2010 17:32:27 +0000 Subject: [PATCH 16/82] * Updated to ZDoom r2993: - Changed skybox code to use the alpha from the sector plane. - Removed alpha from skybox viewpoints. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1075 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_shared/a_sharedglobal.h | 1 - src/g_shared/a_skies.cpp | 7 ++++++- src/p_spec.cpp | 5 +++-- src/r_plane.cpp | 3 ++- src/r_segs.cpp | 2 ++ src/svnrevision.h | 4 ++-- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index c152bf44..84932145 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -97,7 +97,6 @@ public: bool bInSkybox; bool bAlways; TObjPtr Mate; - fixed_t PlaneAlpha; }; class AStackPoint : public ASkyViewpoint diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp index 0454498e..21edd2ba 100644 --- a/src/g_shared/a_skies.cpp +++ b/src/g_shared/a_skies.cpp @@ -69,7 +69,12 @@ void ASkyViewpoint::BeginPlay () void ASkyViewpoint::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << bInSkybox << bAlways << Mate << PlaneAlpha; + arc << bInSkybox << bAlways << Mate; + if (SaveVersion < 2992) + { + fixed_t eatme; + arc << eatme; + } } void ASkyViewpoint::Destroy () diff --git a/src/p_spec.cpp b/src/p_spec.cpp index d48ef90d..79242f52 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -870,7 +870,7 @@ static void SetupFloorPortal (AStackPoint *point) if (Sector->FloorSkyBox != NULL) { Sector->FloorSkyBox->Mate = point; - Sector->FloorSkyBox->PlaneAlpha = Scale (point->args[0], OPAQUE, 255); + Sector->SetAlpha(sector_t::floor, Scale (point->args[0], OPAQUE, 255)); } } @@ -882,7 +882,7 @@ static void SetupCeilingPortal (AStackPoint *point) if (Sector->CeilingSkyBox != NULL) { Sector->CeilingSkyBox->Mate = point; - Sector->CeilingSkyBox->PlaneAlpha = Scale (point->args[0], OPAQUE, 255); + Sector->SetAlpha(sector_t::ceiling, Scale (point->args[0], OPAQUE, 255)); } } @@ -919,6 +919,7 @@ void P_SetupPortals() fixed_t deltay1 = points[i]->Mate->y - points[i]->y; fixed_t deltax2 = points[j]->Mate->x - points[j]->x; fixed_t deltay2 = points[j]->Mate->y - points[j]->y; + if (deltax1 == deltax2 && deltay1 == deltay2) { if (points[j]->Sector->FloorSkyBox == points[j]->Mate) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index a5a40bc1..abf813fd 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -561,6 +561,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl plane = height; isskybox = false; sky = 0; // not skyflatnum so it can't be a sky + skybox = NULL; alpha = FRACUNIT; } @@ -728,6 +729,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop) new_pl->viewz = pl->viewz; new_pl->viewangle = pl->viewangle; new_pl->sky = pl->sky; + new_pl->alpha = pl->alpha; pl = new_pl; pl->minx = start; pl->maxx = stop; @@ -1178,7 +1180,6 @@ void R_DrawSkyBoxes () viewxStack.Push (viewx); viewyStack.Push (viewy); viewzStack.Push (viewz); - pl->alpha = sky->PlaneAlpha; visplaneStack.Push (pl); R_RenderBSPNode (nodes + numnodes - 1); diff --git a/src/r_segs.cpp b/src/r_segs.cpp index eed5d78a..55f80649 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1295,6 +1295,7 @@ void R_NewWall (bool needlights) // killough 3/7/98: Add checks for (x,y) offsets || backsector->GetXOffset(sector_t::floor) != frontsector->GetXOffset(sector_t::floor) || backsector->GetYOffset(sector_t::floor) != frontsector->GetYOffset(sector_t::floor) + || backsector->GetAlpha(sector_t::floor) != frontsector->GetAlpha(sector_t::floor) // killough 4/15/98: prevent 2s normals // from bleeding through deep water @@ -1326,6 +1327,7 @@ void R_NewWall (bool needlights) // killough 3/7/98: Add checks for (x,y) offsets || backsector->GetXOffset(sector_t::ceiling) != frontsector->GetXOffset(sector_t::ceiling) || backsector->GetYOffset(sector_t::ceiling) != frontsector->GetYOffset(sector_t::ceiling) + || backsector->GetAlpha(sector_t::ceiling) != frontsector->GetAlpha(sector_t::ceiling) // killough 4/15/98: prevent 2s normals // from bleeding through fake ceilings diff --git a/src/svnrevision.h b/src/svnrevision.h index ec45a847..e14c2998 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2992" -#define ZD_SVN_REVISION_NUMBER 2992 +#define ZD_SVN_REVISION_STRING "2993" +#define ZD_SVN_REVISION_NUMBER 2993 From af7dcb8d16692ecde3bc776de77f8a5bdd138a45 Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 7 Nov 2010 17:47:48 +0000 Subject: [PATCH 17/82] - Adapted OpenGL code to sector/skybox alpha handling. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1076 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_flats.cpp | 4 ++-- src/gl/scene/gl_renderhacks.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index eccae0f4..d8c6ccc1 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -609,7 +609,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = GetFloorLight(frontsector); Colormap=frontsector->ColorMap; stack = frontsector->FloorSkyBox && frontsector->FloorSkyBox->bAlways; - alpha= stack ? frontsector->FloorSkyBox->PlaneAlpha/65536.0f : 1.0f-frontsector->GetFloorReflect(); + alpha= stack ? frontsector->GetAlpha(sector_t::floor)/65536.0f : 1.0f-frontsector->GetFloorReflect(); if (frontsector->VBOHeightcheck(sector_t::floor)) { vboindex = frontsector->vboindex[sector_t::floor]; @@ -651,7 +651,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = GetCeilingLight(frontsector); Colormap=frontsector->ColorMap; stack = frontsector->CeilingSkyBox && frontsector->CeilingSkyBox->bAlways; - alpha=stack ? frontsector->CeilingSkyBox->PlaneAlpha/65536.0f : 1.0f-frontsector->GetCeilingReflect(); + alpha=stack ? frontsector->GetAlpha(sector_t::ceiling)/65536.0f : 1.0f-frontsector->GetCeilingReflect(); if (frontsector->VBOHeightcheck(sector_t::ceiling)) { vboindex = frontsector->vboindex[sector_t::ceiling]; diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index 0b80d3da..c03b9186 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -1175,7 +1175,7 @@ void FDrawInfo::ProcessSectorStacks() { ss_renderflags[DWORD(HandledSubsectors[j]-subsectors)] &= ~SSRF_RENDERCEILING; - if (sub->render_sector->CeilingSkyBox->PlaneAlpha!=0) + if (sub->render_sector->GetAlpha(sector_t::ceiling)!=0) { gl_subsectorrendernode * node = SSR_List.GetNew(); node->sub = HandledSubsectors[j]; @@ -1212,7 +1212,7 @@ void FDrawInfo::ProcessSectorStacks() //Printf("%d: ss %d, sec %d\n", j, HandledSubsectors[j]-subsectors, HandledSubsectors[j]->render_sector->sectornum); ss_renderflags[DWORD(HandledSubsectors[j]-subsectors)] &= ~SSRF_RENDERFLOOR; - if (sub->render_sector->FloorSkyBox->PlaneAlpha!=0) + if (sub->render_sector->GetAlpha(sector_t::floor)!=0) { gl_subsectorrendernode * node = SSR_List.GetNew(); node->sub = HandledSubsectors[j]; From 6cd2d909203a63930dc67dc8a9920f0cd30f3068 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 Nov 2010 07:24:25 +0000 Subject: [PATCH 18/82] Update to ZDoom r3001: - fixed typo in Firemace obituary - Added DavidPH's AProp_ScaleX/Y / A_SetScale submission. - added Edward-san's fix for the turbo CCMD. - Changed savegame versioning for SVN-less builds to use a SAVEVER value of 999999 so that it is guaranteed that such a build can load its own savegames - even if it is at the cost of losing the ability to handle older savegames. People should build ZDoom with revision info anyway. ;) - fixed: Sector_SetPortal did not set the portal's alpha value. - added 'flooralpha' and 'ceilingalpha' sector properties. They only have meaning if a sector stack portal is defined in this sector. If set to anything less than 1.0 these will override the alpha set by a portal. This is mostly for Sector_SetPortal to avoid defining multiple portals that only differ by their plane translucency. - fixed: Explosions may not spawn splashes in sectors with a Transfer_Heights effect. Due to the way it handles floor textures it cannot spawn them correctly there. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1077 b0f79afe-0144-0410-b225-9a4edf0717df --- specs/udmf_zdoom.txt | 2 ++ src/g_game.cpp | 4 ++-- src/namedef.h | 2 ++ src/p_acs.cpp | 18 ++++++++++++++++-- src/p_mobj.cpp | 2 +- src/p_spec.cpp | 24 +++++++++++++++++------- src/p_udmf.cpp | 10 ++++++++++ src/svnrevision.h | 4 ++-- src/thingdef/thingdef_codeptr.cpp | 18 ++++++++++++++++++ src/thingdef/thingdef_expression.cpp | 3 +++ src/version.h | 5 +++-- wadsrc/static/actors/actor.txt | 3 +++ wadsrc/static/language.enu | 2 +- 13 files changed, 80 insertions(+), 17 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index fef3fa99..1a4dbeff 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -153,6 +153,8 @@ Note: All fields default to false unless mentioned otherwise. // relative to the owning sector's light level. lightceilingabsolute = ; // true = 'lightceiling' is an absolute value. Default is // relative to the owning sector's light level. + alphafloor = ; // translucency of floor plane (only has meaning with Sector_SetPortal) Default is 1.0. + alphaceiling = ; // translucency of ceiling plane (only has meaning with Sector_SetPortal) Default is 1.0. gravity = ; // Sector's gravity. Default is 1.0. lightcolor = ; // Sector'S light color as RRGGBB value, default = 0xffffff. fadecolor = ; // Sector'S fog color as RRGGBB value, default = 0x000000. diff --git a/src/g_game.cpp b/src/g_game.cpp index 1153a9e7..19acf8c5 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -240,9 +240,9 @@ CUSTOM_CVAR (Float, turbo, 100.f, 0) { self = 10.f; } - else if (self > 256.f) + else if (self > 255.f) { - self = 256.f; + self = 255.f; } else { diff --git a/src/namedef.h b/src/namedef.h index 4a00c99c..684d447f 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -419,6 +419,8 @@ xx(Silent) xx(Nofallingdamage) xx(Dropactors) xx(NoRespawn) +xx(Alphafloor) +xx(Alphaceiling) xx(offsetx_top) xx(offsety_top) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index e7fff7d7..34275da1 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -312,6 +312,7 @@ static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count { SDWORD key, val; key = arc.ReadCount(); + val = arc.ReadCount(); vars[i].Insert (key, val); } @@ -2537,8 +2538,10 @@ enum APROP_MasterTID = 25, APROP_TargetTID = 26, APROP_TracerTID = 27, - APROP_WaterLevel = 28 -}; + APROP_WaterLevel = 28, + APROP_ScaleX = 29, + APROP_ScaleY = 30, +}; // These are needed for ACS's APROP_RenderStyle static const int LegacyRenderStyleIndices[] = @@ -2718,6 +2721,14 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) DoSetMaster (actor, other); break; + case APROP_ScaleX: + actor->scaleX = value; + break; + + case APROP_ScaleY: + actor->scaleY = value; + break; + default: // do nothing. break; @@ -2780,6 +2791,9 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_TargetTID: return (actor->target != NULL)? actor->target->tid : 0; case APROP_TracerTID: return (actor->tracer != NULL)? actor->tracer->tid : 0; case APROP_WaterLevel: return actor->waterlevel; + case APROP_ScaleX: return actor->scaleX; + case APROP_ScaleY: return actor->scaleY; + default: return 0; } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 79c20c1e..adfbeb0e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4913,7 +4913,7 @@ bool P_HitFloor (AActor *thing) void P_CheckSplash(AActor *self, fixed_t distance) { - if (self->z <= self->floorz + (distance<floorsector == self->Sector) + if (self->z <= self->floorz + (distance<floorsector == self->Sector && self->Sector->GetHeightSec() == NULL) { // Explosion splashes never alert monsters. This is because A_Explode has // a separate parameter for that so this would get in the way of proper diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 79242f52..0ba2f01d 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -870,7 +870,8 @@ static void SetupFloorPortal (AStackPoint *point) if (Sector->FloorSkyBox != NULL) { Sector->FloorSkyBox->Mate = point; - Sector->SetAlpha(sector_t::floor, Scale (point->args[0], OPAQUE, 255)); + if (Sector->GetAlpha(sector_t::floor) == OPAQUE) + Sector->SetAlpha(sector_t::floor, Scale (point->args[0], OPAQUE, 255)); } } @@ -882,7 +883,8 @@ static void SetupCeilingPortal (AStackPoint *point) if (Sector->CeilingSkyBox != NULL) { Sector->CeilingSkyBox->Mate = point; - Sector->SetAlpha(sector_t::ceiling, Scale (point->args[0], OPAQUE, 255)); + if (Sector->GetAlpha(sector_t::ceiling) == OPAQUE) + Sector->SetAlpha(sector_t::ceiling, Scale (point->args[0], OPAQUE, 255)); } } @@ -936,16 +938,23 @@ void P_SetupPortals() } } -inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal) +inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t alpha) { // plane: 0=floor, 1=ceiling, 2=both if (plane > 0) { - if (sector->CeilingSkyBox == NULL) sector->CeilingSkyBox = portal; + if (sector->CeilingSkyBox == NULL) + { + sector->CeilingSkyBox = portal; + if (sector->GetAlpha(sector_t::ceiling) == OPAQUE) + sector->SetAlpha(sector_t::ceiling, alpha); + } } if (plane == 2 || plane == 0) { if (sector->FloorSkyBox == NULL) sector->FloorSkyBox = portal; + if (sector->GetAlpha(sector_t::floor) == OPAQUE) + sector->SetAlpha(sector_t::floor, alpha); } } @@ -965,6 +974,7 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha) fixed_t y1 = (line->v1->y + line->v2->y) >> 1; fixed_t x2 = (lines[i].v1->x + lines[i].v2->x) >> 1; fixed_t y2 = (lines[i].v1->y + lines[i].v2->y) >> 1; + fixed_t alpha = Scale (lines[i].args[4], OPAQUE, 255); AStackPoint *anchor = Spawn(x1, y1, 0, NO_REPLACE); AStackPoint *reference = Spawn(x2, y2, 0, NO_REPLACE); @@ -979,7 +989,7 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha) for (int s=-1; (s = P_FindSectorFromTag(sectortag,s)) >= 0;) { - SetPortal(§ors[s], plane, reference); + SetPortal(§ors[s], plane, reference, alpha); } for (int j=0;j= 0;) { - SetPortal(§ors[s], plane, reference); + SetPortal(§ors[s], plane, reference, alpha); } } } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 8ae9403b..0fba825b 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1074,6 +1074,8 @@ public: sec->SetYScale(sector_t::floor, FRACUNIT); sec->SetXScale(sector_t::ceiling, FRACUNIT); sec->SetYScale(sector_t::ceiling, FRACUNIT); + sec->SetAlpha(sector_t::floor, FRACUNIT); + sec->SetAlpha(sector_t::ceiling, FRACUNIT); sec->thinglist = NULL; sec->touching_thinglist = NULL; // phares 3/14/98 sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1; @@ -1185,6 +1187,14 @@ public: sec->SetPlaneLight(sector_t::ceiling, CheckInt(key)); continue; + case NAME_Alphafloor: + sec->SetAlpha(sector_t::floor, CheckFixed(key)); + continue; + + case NAME_Alphaceiling: + sec->SetAlpha(sector_t::ceiling, CheckFixed(key)); + continue; + case NAME_Lightfloorabsolute: if (CheckBool(key)) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); else sec->ChangeFlags(sector_t::floor, PLANEF_ABSLIGHTING, 0); diff --git a/src/svnrevision.h b/src/svnrevision.h index e14c2998..0904ce2e 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2993" -#define ZD_SVN_REVISION_NUMBER 2993 +#define ZD_SVN_REVISION_STRING "3001" +#define ZD_SVN_REVISION_NUMBER 3001 diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 1ac84d38..a40c4946 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2020,6 +2020,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeTo) } } +//=========================================================================== +// +// A_Scale(float scalex, optional float scaley) +// +// Scales the actor's graphics. If scaley is 0, use scalex. +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetScale) +{ + ACTION_PARAM_START(2); + ACTION_PARAM_FIXED(scalex, 0); + ACTION_PARAM_FIXED(scaley, 1); + + self->scaleX = scalex; + self->scaleY = scaley ? scaley : scalex; +} + //=========================================================================== // // A_SpawnDebris @@ -2632,6 +2649,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) { + return; // [KS] Outside of FOV - return } diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 9440a05b..1315d70e 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -77,6 +77,8 @@ DEFINE_MEMBER_VARIABLE(velz, AActor) DEFINE_MEMBER_VARIABLE_ALIAS(momx, velx, AActor) DEFINE_MEMBER_VARIABLE_ALIAS(momy, vely, AActor) DEFINE_MEMBER_VARIABLE_ALIAS(momz, velz, AActor) +DEFINE_MEMBER_VARIABLE(scaleX, AActor) +DEFINE_MEMBER_VARIABLE(scaleY, AActor) DEFINE_MEMBER_VARIABLE(Damage, AActor) DEFINE_MEMBER_VARIABLE(Score, AActor) @@ -675,6 +677,7 @@ FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx) { CHECKRESOLVED(); if (Operand) + { Operand = Operand->ResolveAsBoolean(ctx); } diff --git a/src/version.h b/src/version.h index cf688125..bb3cd5f4 100644 --- a/src/version.h +++ b/src/version.h @@ -80,8 +80,9 @@ #define MINSAVEVER 1848 #if ZD_SVN_REVISION_NUMBER < MINSAVEVER -// Never write a savegame with a version lower than what we need -#define SAVEVER MINSAVEVER +// If we don't know the current revision write something very high to ensure that +// the reesulting executable can read its own savegames but no regular engine can. +#define SAVEVER 999999 #define SAVESIG MakeSaveSig() static inline const char *MakeSaveSig() { diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index fb065552..f8dd3d86 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -47,6 +47,8 @@ ACTOR Actor native //: Thinker native fixed_t momx; // alias for velx native fixed_t momy; // alias for vely native fixed_t momz; // alias for velz + native fixed_t scaleX; + native fixed_t scaleY; native int score; // Meh, MBF redundant functions. Only for DeHackEd support. @@ -204,6 +206,7 @@ ACTOR Actor native //: Thinker action native A_FadeIn(float reduce = 0.1); action native A_FadeOut(float reduce = 0.1, bool remove = true); action native A_FadeTo(float target, float amount = 0.1, bool remove = false); + action native A_SetScale(float scalex, float scaley = 0); action native A_SpawnDebris(class spawntype, bool transfer_translation = false, float mult_h = 1, float mult_v = 1); action native A_CheckSight(state label); action native A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false); diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 1a222f1f..3acfe404 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -737,7 +737,7 @@ OB_MPCROSSBOW = "%o was pegged by %k's ethereal crossbow."; OB_MPBLASTER = "%o was blasted a new one by %k's dragon claw."; OB_MPSKULLROD = "%o got sent down under by %k's hellstaff."; OB_MPPHOENIXROD = "%o was scorched to cinders by %k's phoenix rod."; -OB_MPMACE = "%o was bounced by $k's firemace."; +OB_MPMACE = "%o was bounced by %k's firemace."; OB_MPPSTAFF = "%o got clapped by %k's charged staff."; OB_MPPGAUNTLETS = "%o was bled dry by %k's gauntlets."; From d7799a0d5874b7b006b59f7a88bfb103439db4db Mon Sep 17 00:00:00 2001 From: gez Date: Mon, 8 Nov 2010 15:06:45 +0000 Subject: [PATCH 19/82] - Updated CheckActorProperty for waterlevel and scale checks. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1078 b0f79afe-0144-0410-b225-9a4edf0717df --- src/p_acs.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 34275da1..7a477acc 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2827,6 +2827,9 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_MasterTID: case APROP_TargetTID: case APROP_TracerTID: + case APROP_WaterLevel: + case APROP_ScaleX: + case APROP_ScaleY: return (GetActorProperty(tid, property) == value); // Boolean values need to compare to a binary version of value From a9e96a6315271b4a0027a1af38c93abefefd7349 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 Nov 2010 20:22:18 +0000 Subject: [PATCH 20/82] - fixed: The floorplane's alpha was not initialized. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1079 b0f79afe-0144-0410-b225-9a4edf0717df --- src/p_setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index f8233ce3..bb274bbc 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1460,7 +1460,7 @@ void P_LoadSectors (MapData * map) ss->nextsec = -1; //jff 2/26/98 add fields to support locking out ss->prevsec = -1; // stair retriggering until build completes - ss->SetAlpha(sector_t::ceiling, FRACUNIT); + ss->SetAlpha(sector_t::floor, FRACUNIT); ss->SetAlpha(sector_t::ceiling, FRACUNIT); ss->SetXScale(sector_t::floor, FRACUNIT); // [RH] floor and ceiling scaling ss->SetYScale(sector_t::floor, FRACUNIT); From 17e3af22e4b8782baa4ae4fa29523f93b1c3b57b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 Nov 2010 23:42:26 +0000 Subject: [PATCH 21/82] - fixed a vertex mixup in the portal clipping code. This was causing glitches in KDiZD's Z1M3. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1080 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_portal.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index b4ba4936..5c068856 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -692,17 +692,17 @@ int GLSectorStackPortal::ClipSeg(seg_t *seg) if (angles[j+1] - clipangle <= ANGLE_180 && angles[j] - clipangle > ANGLE_180 && angles[j+1] - angles[j] < ANGLE_180) { relation = DMulScale32(seg->v2->y - portal->Shape[j]->y - portal->yDisplacement, portal->Shape[j+1]->x - portal->Shape[j]->x, - portal->Shape[j]->x - seg->v1->x + portal->xDisplacement, portal->Shape[j+1]->y - portal->Shape[j]->y); + portal->Shape[j]->x - seg->v2->x + portal->xDisplacement, portal->Shape[j+1]->y - portal->Shape[j]->y); if (relation > 0) { return PClip_InFront; } else if (relation == 0) { - // If this vertex is on the boundary we need to check the second one, too. The line may be partially inside the shape + // If this vertex is on the boundary we need to check the other one, too. The line may be partially inside the shape // but outside the portal. We can use the same boundary line for this - relation = DMulScale32(seg->v2->y - portal->Shape[j]->y - portal->yDisplacement, portal->Shape[j+1]->x - portal->Shape[j]->x, - portal->Shape[j]->x - seg->v2->x + portal->xDisplacement, portal->Shape[j+1]->y - portal->Shape[j]->y); + relation = DMulScale32(seg->v1->y - portal->Shape[j]->y - portal->yDisplacement, portal->Shape[j+1]->x - portal->Shape[j]->x, + portal->Shape[j]->x - seg->v1->x + portal->xDisplacement, portal->Shape[j+1]->y - portal->Shape[j]->y); if (relation >= 0) return PClip_InFront; } return PClip_Inside; From d54ed104ff7a437a1fc3941d062f904e53fd079b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 8 Nov 2010 23:45:55 +0000 Subject: [PATCH 22/82] - $musicalias SNDINFO command. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1081 b0f79afe-0144-0410-b225-9a4edf0717df --- src/s_advsound.cpp | 30 ++++++++++++++++++++++++++++++ src/s_sound.cpp | 10 +++++++++- src/s_sound.h | 2 ++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 240498f0..c194d744 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -149,6 +149,7 @@ enum SICommands SI_IfStrife, SI_Rolloff, SI_Volume, + SI_MusicAlias, }; // Blood was a cool game. If Monolith ever releases the source for it, @@ -183,6 +184,7 @@ struct FSavedPlayerSoundInfo }; // This specifies whether Timidity or Windows playback is preferred for a certain song (only useful for Windows.) +MusicAliasMap MusicAliases; MidiDeviceMap MidiDevices; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -241,6 +243,7 @@ static const char *SICommandStrings[] = "$ifstrife", "$rolloff", "$volume", + "$musicalias", NULL }; @@ -254,6 +257,7 @@ static bool PlayerClassesIsSorted; static TArray PlayerClassLookups; static TArray PlayerSounds; + static FString DefPlayerClassName; static int DefPlayerClass; @@ -1285,6 +1289,32 @@ static void S_AddSNDINFO (int lump) } break; + case SI_MusicAlias: { + sc.MustGetString(); + int lump = Wads.CheckNumForName(sc.String, ns_music); + if (lump >= 0) + { + // do not set the alias if a later WAD defines its own music of this name + int file = Wads.GetLumpFile(lump); + int sndifile = Wads.GetLumpFile(sc.LumpNum); + if (file > sndifile) + { + sc.MustGetString(); + continue; + } + } + FName alias = sc.String; + sc.MustGetString(); + FName mapped = sc.String; + + // only set the alias if the lump it maps to exists. + if (mapped == NAME_None || Wads.CheckNumForName(sc.String, ns_music) >= 0) + { + MusicAliases[alias] = mapped; + } + } + break; + case SI_MidiDevice: { sc.MustGetString(); FName nm = sc.String; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 95130d30..bb85541c 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -2386,8 +2386,16 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) int offset = 0, length = 0; int device = MDEV_DEFAULT; MusInfo *handle = NULL; + FName musicasname = musicname; - int *devp = MidiDevices.CheckKey(FName(musicname)); + FName *aliasp = MusicAliases.CheckKey(musicasname); + if (aliasp != NULL) + { + musicname = (musicasname = *aliasp).GetChars(); + if (musicasname == NAME_None) return true; + } + + int *devp = MidiDevices.CheckKey(musicasname); if (devp != NULL) device = *devp; // Strip off any leading file:// component. diff --git a/src/s_sound.h b/src/s_sound.h index 5c2796d5..ee831bdd 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -382,8 +382,10 @@ enum EMidiDevice MDEV_GUS = 5, }; +typedef TMap MusicAliasMap; typedef TMap MidiDeviceMap; +extern MusicAliasMap MusicAliases; extern MidiDeviceMap MidiDevices; #endif From ebb060892589ca49086dbbd970457d5cfca7799f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 Nov 2010 17:29:51 +0000 Subject: [PATCH 23/82] - added a handler for sectors with the floors above the ceiling. They caused texture overlap glitches. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1082 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_fakeflat.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/gl/scene/gl_fakeflat.cpp b/src/gl/scene/gl_fakeflat.cpp index 5d00972e..f3b452ca 100644 --- a/src/gl/scene/gl_fakeflat.cpp +++ b/src/gl/scene/gl_fakeflat.cpp @@ -206,7 +206,23 @@ bool CopyPlaneIfValid (secplane_t *dest, const secplane_t *source, const secplan //========================================================================== sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back) { - if (!sec->heightsec || sec->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC || sec->heightsec==sec) return sec; + if (!sec->heightsec || sec->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC || sec->heightsec==sec) + { + // check for backsectors with the ceiling lower than the floor. These will create + // visual glitches because upper amd lower textures overlap. + if (back && sec->planes[sector_t::floor].TexZ > sec->planes[sector_t::ceiling].TexZ) + { + if (!(sec->floorplane.a | sec->floorplane.b | sec->ceilingplane.a | sec->ceilingplane.b)) + { + *dest = *sec; + dest->ceilingplane=sec->floorplane; + dest->ceilingplane.FlipVert(); + dest->planes[sector_t::ceiling].TexZ = dest->planes[sector_t::floor].TexZ; + return dest; + } + } + return sec; + } #ifdef _MSC_VER #ifdef _DEBUG From a7797d8d429eec9874b436790ec0452d7bfcd96d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Nov 2010 17:39:15 +0000 Subject: [PATCH 24/82] - foxed: The ceiling plane should not clip mid textures if there's sky on both sides of it. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1083 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_portaldata.cpp | 373 +++++++++++++++++++++++++++++++++- src/gl/data/gl_setup.cpp | 19 +- src/gl/scene/gl_walls.cpp | 15 +- src/r_defs.h | 7 + 4 files changed, 397 insertions(+), 17 deletions(-) diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index 239ff0b4..c3c71cc4 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -203,6 +203,331 @@ void FPortal::UpdateClipAngles() } } + + +//========================================================================== +// +// +// +//========================================================================== + +struct FCoverageVertex +{ + fixed_t x, y; +}; + +struct FCoverageBuilder +{ + subsector_t *target; + FPortal *portal; + TArray collect; + FCoverageVertex center; + + //========================================================================== + // + // + // + //========================================================================== + + FCoverageBuilder(subsector_t *sub, FPortal *port) + { + target = sub; + portal = port; + } + + //========================================================================== + // + // GetIntersection + // + // adapted from P_InterceptVector + // + //========================================================================== + + bool GetIntersection(FCoverageVertex *v1, FCoverageVertex *v2, node_t *bsp, FCoverageVertex *v) + { + double frac; + double num; + double den; + + double v2x = (double)v1->x; + double v2y = (double)v1->y; + double v2dx = (double)(v2->x - v1->x); + double v2dy = (double)(v2->y - v1->y); + double v1x = (double)bsp->x; + double v1y = (double)bsp->y; + double v1dx = (double)bsp->dx; + double v1dy = (double)bsp->dy; + + den = v1dy*v2dx - v1dx*v2dy; + + if (den == 0) + return false; // parallel + + num = (v1x - v2x)*v1dy + (v2y - v1y)*v1dx; + frac = num / den; + + if (frac < 0. || frac > 1.) return false; + + v->x = xs_RoundToInt(v2x + frac * v2dx); + v->y = xs_RoundToInt(v2y + frac * v2dy); + return true; + } + + //========================================================================== + // + // + // + //========================================================================== + + double PartitionDistance(FCoverageVertex *vt, node_t *node) + { + return fabs(double(-node->dy) * (vt->x - node->x) + double(node->dx) * (vt->y - node->y)) / node->len; + } + + //========================================================================== + // + // + // + //========================================================================== + + int PointOnSide(FCoverageVertex *vt, node_t *node) + { + return R_PointOnSide(vt->x, vt->y, node); + } + + //========================================================================== + // + // + // + //========================================================================== + + void CollectSubsector(subsector_t *sub, TArray &shape) + { +#if 1 + collect.Push(int(sub-subsectors)); +#else + divline_t shapeline; + divline_t subline; + double cx, cy; + fixed_t fcx, fcy; + unsigned int matches; + + for(unsigned j = 0; j < shape.Size(); j++) + { + int jj = (j+1)%shape.Size(); + shapeline.x = shape[j].x; + shapeline.y = shape[j].y; + shapeline.dx = shape[jj].x - shape[j].x; + shapeline.dy = shape[jj].y - shape[j].y; + for(unsigned i = 0; i < sub->numlines; i++) + { + subline.x = sub->firstline[i].v1->x; + subline.y = sub->firstline[i].v1->y; + subline.dx = sub->firstline[i].v2->x - subline.x; + subline.dy = sub->firstline[i].v2->y - subline.y; + } + fixed_t inter1 = P_InterceptVector(&subline, &shapeline); + fixed_t inter2 = P_InterceptVector(&shapeline, &subline); + if (inter1 > 0 && inter1 < FRACUNIT && inter2 > 0 && inter2 < FRACUNIT) + { + collect.Push(int(sub-subsectors)); + return; + } + } + // If we get here the subsector's lines don't intersect with the shape. + // There's 3 possibilities: + // 1: The shape is inside the subsector (and therefore the shape's center is inside the subsector) + cx = cy = 0; + for(unsigned j = 0; j < shape.Size(); j++) + { + cx += shape[j].x; + cy += shape[j].y; + } + fcx = xs_CRoundToInt(cx / shape.Size()); + fcy = xs_CRoundToInt(cy / shape.Size()); + + matches = 0; + for(unsigned i = 0; i < sub->numlines; i++) + { + subline.x = sub->firstline[i].v1->x; + subline.y = sub->firstline[i].v1->y; + subline.dx = sub->firstline[i].v2->x - subline.x; + subline.dy = sub->firstline[i].v2->y - subline.y; + matches += P_PointOnDivlineSide(fcx, fcy, &subline); + } + if (matches == sub->numlines) + { + collect.Push(int(sub-subsectors)); + return; + } + + // 2: The subsector is inside the shape (and therefore the subsector's center is inside the shape) + cx = cy = 0; + for(unsigned i = 0; i < sub->numlines; i++) + { + cx += sub->firstline[i].v1->x; + cy += sub->firstline[i].v1->y; + } + fcx = xs_CRoundToInt(cx / sub->numlines); + fcy = xs_CRoundToInt(cy / sub->numlines); + + matches = 0; + for(unsigned j = 0; j < shape.Size(); j++) + { + int jj = (j+1)%shape.Size(); + shapeline.x = shape[j].x; + shapeline.y = shape[j].y; + shapeline.dx = shape[jj].x - shape[j].x; + shapeline.dy = shape[jj].y - shape[j].y; + matches += P_PointOnDivlineSide(fcx, fcy, &shapeline); + } + if (matches == (int)shape.Size()) + { + collect.Push(int(sub-subsectors)); + return; + } + + // 3: Both are completely separate. No need to check because this isn't part of the coverage. +#endif + } + + //========================================================================== + // + // adapted from polyobject splitter but uses a more precise epsilon + // + //========================================================================== + + void CollectNode(void *node, TArray &shape) + { + static TArray lists[2]; + static const double COVERAGE_EPSILON = 6./FRACUNIT; // same epsilon as the node builder + + if (!((size_t)node & 1)) // Keep going until found a subsector + { + node_t *bsp = (node_t *)node; + + int centerside = R_PointOnSide(centerx, centery, bsp); + + lists[0].Clear(); + lists[1].Clear(); + for(unsigned i=0;ichildren[0], shape); + } + else if (lists[0].Size() == 0) + { + CollectNode(bsp->children[1], shape); + } + else + { + // copy the static arrays into local ones + TArray locallist0 = lists[0]; + TArray locallist1 = lists[1]; + + CollectNode(bsp->children[0], locallist0); + CollectNode(bsp->children[1], locallist1); + } + } + else + { + // we reached a subsector so we can link the node with this subsector + subsector_t *sub = (subsector_t *)((BYTE *)node - 1); + + CollectSubsector(sub, shape); + } + } +}; + +//========================================================================== +// +// Calculate portal coverage for a single subsector +// +//========================================================================== + +void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal) +{ + TArray shape; + double centerx=0, centery=0; + + shape.Resize(subsector->numlines); + for(unsigned i=0; inumlines; i++) + { + centerx += (shape[i].x = subsector->firstline[i].v1->x + portal->xDisplacement); + centery += (shape[i].y = subsector->firstline[i].v1->y + portal->yDisplacement); + } + + FCoverageBuilder build(subsector, portal); + build.center.x = xs_CRoundToInt(centerx / subsector->numlines); + build.center.y = xs_CRoundToInt(centery / subsector->numlines); + + if (numnodes == 0) + { + build.CollectSubsector (subsectors, shape); + } + else + { + build.CollectNode(nodes + numnodes - 1, shape); + } + coverage->subsectors = new DWORD[build.collect.Size()]; + coverage->sscount = build.collect.Size(); + memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(DWORD)); +} + //========================================================================== // // portal initialization @@ -211,6 +536,10 @@ void FPortal::UpdateClipAngles() void gl_InitPortals() { + glcycle_t tpt; + tpt.Reset(); + tpt.Clock(); + TThinkerIterator it; AStackPoint *pt; @@ -248,17 +577,25 @@ void gl_InitPortals() } portal->AddSectorToPortal(§ors[i]); portal->plane|=plane; + + for (int j=0;j < sectors[i].subsectorcount; j++) + { + subsector_t *sub = sectors[i].subsectors[j]; + gl_BuildPortalCoverage(&sub->portalcoverage[plane-1], sub, portal); + } } if (portal != NULL) { // if the first vertex is duplicated at the end it'll save time in a time critical function - // because that code does not need to check for wraparounds anymire. + // because that code does not need to check for wraparounds anymore. portal->Shape.Resize(portal->Shape.Size()+1); portal->Shape[portal->Shape.Size()-1] = portal->Shape[0]; portal->Shape.ShrinkToFit(); portal->ClipAngles.Resize(portal->Shape.Size()); } } + tpt.Unclock(); + Printf("Portal init took %f ms\n", tpt.TimeMS()); } @@ -266,11 +603,39 @@ CCMD(dumpportals) { for(unsigned i=0;ix/65536., portals[i].origin->y/65536., - portals[i].origin->x/65536. - portals[i].origin->Mate->x/65536., portals[i].origin->y/65536. - portals[i].origin->Mate->y/65536.); + double xdisp = portals[i].xDisplacement/65536.; + double ydisp = portals[i].yDisplacement/65536.; + Printf(PRINT_LOG, "Portal #%d, plane %d, stackpoint at (%f,%f), displacement = (%f,%f)\nShape:\n", i, portals[i].plane, portals[i].origin->x/65536., portals[i].origin->y/65536., + xdisp, ydisp); for (unsigned j=0;jx + portals[i].xDisplacement)/65536., (portals[i].Shape[j]->y + portals[i].yDisplacement)/65536.); + Printf(PRINT_LOG, "\t(%f,%f)\n", portals[i].Shape[j]->x/65536. + xdisp, portals[i].Shape[j]->y/65536. + ydisp); + } + Printf(PRINT_LOG, "Coverage:\n"); + for(int j=0;jrender_sector->FloorSkyBox : sub->render_sector->CeilingSkyBox; + if (pt != NULL && pt->bAlways && pt->special1 == i) + { + Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", j, sub->render_sector->sectornum); + for(unsigned k = 0;k< sub->numlines; k++) + { + Printf(PRINT_LOG, "(%.3f,%.3f), ", sub->firstline[k].v1->x/65536. + xdisp, sub->firstline[k].v1->y/65536. + ydisp); + } + Printf(PRINT_LOG, "\n\t\tCovered by subsectors:\n"); + FPortalCoverage *cov = &sub->portalcoverage[portals[i].plane-1]; + for(int l = 0;l< cov->sscount; l++) + { + subsector_t *csub = &subsectors[cov->subsectors[l]]; + Printf(PRINT_LOG, "\t\t\t%5d (%4d): ", cov->subsectors[l], csub->render_sector->sectornum); + for(unsigned m = 0;m< csub->numlines; m++) + { + Printf(PRINT_LOG, "(%.3f,%.3f), ", csub->firstline[m].v1->x/65536., csub->firstline[m].v1->y/65536.); + } + Printf(PRINT_LOG, "\n"); + } + } } } } diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index 42c0bf90..dd1d3f1d 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -587,17 +587,16 @@ void gl_CleanLevelData() delete [] sectors[0].subsectors; sectors[0].subsectors = NULL; } - if (gamenodes && gamenodes!=nodes) + for (int i=0;isidedef->GetTexture(side_t::top)); if (!tex || tex->UseType==FTexture::TEX_Null) { - // texture is missing - use the higher plane - topleft = MAX(bch1,fch1); - topright = MAX(bch2,fch2); + if (seg->frontsector->GetTexture(sector_t::ceiling) == skyflatnum && + seg->backsector->GetTexture(sector_t::ceiling) == skyflatnum) + { + // intra-sky lines do not clip the texture at all if there's no upper texture + topleft = topright = texturetop; + } + else + { + // texture is missing - use the higher plane + topleft = MAX(bch1,fch1); + topright = MAX(bch2,fch2); + } } else if ((bch1>fch1 || bch2>fch2) && (seg->frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || seg->backsector->GetTexture(sector_t::ceiling)==skyflatnum)) diff --git a/src/r_defs.h b/src/r_defs.h index d1ba877b..e4f93684 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1051,6 +1051,12 @@ enum SSECF_POLYORG = 4, }; +struct FPortalCoverage +{ + DWORD * subsectors; + int sscount; +}; + struct subsector_t { sector_t *sector; @@ -1067,6 +1073,7 @@ struct subsector_t int validcount; char hacked; // 1: is part of a render hack // 2: has one-sided walls + FPortalCoverage portalcoverage[2]; }; From b8a3df9285bd4615929f9f3c3ae717a9e773dc0f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 11 Nov 2010 10:38:01 +0000 Subject: [PATCH 25/82] - implemented portal coverage information which hopefully helps resolve most portal clipping issues. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1084 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_portaldata.cpp | 180 ++++++++++------------------------ 1 file changed, 52 insertions(+), 128 deletions(-) diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index c3c71cc4..cb40d6a8 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -214,6 +214,16 @@ void FPortal::UpdateClipAngles() struct FCoverageVertex { fixed_t x, y; + + bool operator !=(FCoverageVertex &other) + { + return x != other.x || y != other.y; + } +}; + +struct FCoverageLine +{ + FCoverageVertex v[2]; }; struct FCoverageBuilder @@ -297,116 +307,20 @@ struct FCoverageBuilder //========================================================================== // - // - // - //========================================================================== - - void CollectSubsector(subsector_t *sub, TArray &shape) - { -#if 1 - collect.Push(int(sub-subsectors)); -#else - divline_t shapeline; - divline_t subline; - double cx, cy; - fixed_t fcx, fcy; - unsigned int matches; - - for(unsigned j = 0; j < shape.Size(); j++) - { - int jj = (j+1)%shape.Size(); - shapeline.x = shape[j].x; - shapeline.y = shape[j].y; - shapeline.dx = shape[jj].x - shape[j].x; - shapeline.dy = shape[jj].y - shape[j].y; - for(unsigned i = 0; i < sub->numlines; i++) - { - subline.x = sub->firstline[i].v1->x; - subline.y = sub->firstline[i].v1->y; - subline.dx = sub->firstline[i].v2->x - subline.x; - subline.dy = sub->firstline[i].v2->y - subline.y; - } - fixed_t inter1 = P_InterceptVector(&subline, &shapeline); - fixed_t inter2 = P_InterceptVector(&shapeline, &subline); - if (inter1 > 0 && inter1 < FRACUNIT && inter2 > 0 && inter2 < FRACUNIT) - { - collect.Push(int(sub-subsectors)); - return; - } - } - // If we get here the subsector's lines don't intersect with the shape. - // There's 3 possibilities: - // 1: The shape is inside the subsector (and therefore the shape's center is inside the subsector) - cx = cy = 0; - for(unsigned j = 0; j < shape.Size(); j++) - { - cx += shape[j].x; - cy += shape[j].y; - } - fcx = xs_CRoundToInt(cx / shape.Size()); - fcy = xs_CRoundToInt(cy / shape.Size()); - - matches = 0; - for(unsigned i = 0; i < sub->numlines; i++) - { - subline.x = sub->firstline[i].v1->x; - subline.y = sub->firstline[i].v1->y; - subline.dx = sub->firstline[i].v2->x - subline.x; - subline.dy = sub->firstline[i].v2->y - subline.y; - matches += P_PointOnDivlineSide(fcx, fcy, &subline); - } - if (matches == sub->numlines) - { - collect.Push(int(sub-subsectors)); - return; - } - - // 2: The subsector is inside the shape (and therefore the subsector's center is inside the shape) - cx = cy = 0; - for(unsigned i = 0; i < sub->numlines; i++) - { - cx += sub->firstline[i].v1->x; - cy += sub->firstline[i].v1->y; - } - fcx = xs_CRoundToInt(cx / sub->numlines); - fcy = xs_CRoundToInt(cy / sub->numlines); - - matches = 0; - for(unsigned j = 0; j < shape.Size(); j++) - { - int jj = (j+1)%shape.Size(); - shapeline.x = shape[j].x; - shapeline.y = shape[j].y; - shapeline.dx = shape[jj].x - shape[j].x; - shapeline.dy = shape[jj].y - shape[j].y; - matches += P_PointOnDivlineSide(fcx, fcy, &shapeline); - } - if (matches == (int)shape.Size()) - { - collect.Push(int(sub-subsectors)); - return; - } - - // 3: Both are completely separate. No need to check because this isn't part of the coverage. -#endif - } - - //========================================================================== - // - // adapted from polyobject splitter but uses a more precise epsilon + // adapted from polyobject splitter // //========================================================================== void CollectNode(void *node, TArray &shape) { - static TArray lists[2]; - static const double COVERAGE_EPSILON = 6./FRACUNIT; // same epsilon as the node builder + static TArray lists[2]; + const double COVERAGE_EPSILON = 6.; // same epsilon as the node builder if (!((size_t)node & 1)) // Keep going until found a subsector { node_t *bsp = (node_t *)node; - int centerside = R_PointOnSide(centerx, centery, bsp); + int centerside = R_PointOnSide(center.x, center.y, bsp); lists[0].Clear(); lists[1].Clear(); @@ -414,6 +328,7 @@ struct FCoverageBuilder { FCoverageVertex *v1 = &shape[i]; FCoverageVertex *v2 = &shape[(i+1) % shape.Size()]; + FCoverageLine vl = { *v1, *v2 }; double dist_v1 = PartitionDistance(v1, bsp); double dist_v2 = PartitionDistance(v2, bsp); @@ -422,18 +337,18 @@ struct FCoverageBuilder { if (dist_v2 <= COVERAGE_EPSILON) { - lists[centerside].Push(*v1); + lists[centerside].Push(vl); } else { int side = PointOnSide(v2, bsp); - lists[side].Push(*v1); + lists[side].Push(vl); } } else if (dist_v2 <= COVERAGE_EPSILON) { int side = PointOnSide(v1, bsp); - lists[side].Push(*v1); + lists[side].Push(vl); } else { @@ -448,20 +363,21 @@ struct FCoverageBuilder if (GetIntersection(v1, v2, bsp, &vert)) { - lists[side1].Push(*v1); - lists[side1].Push(vert); - lists[side2].Push(vert); + lists[0].Push(vl); + lists[1].Push(vl); + lists[side1].Last().v[1] = vert; + lists[side2].Last().v[0] = vert; } else { // should never happen - lists[side1].Push(*v1); + lists[side1].Push(vl); } } else { // both points on the same side. - lists[side1].Push(*v1); + lists[side1].Push(vl); } } } @@ -476,19 +392,30 @@ struct FCoverageBuilder else { // copy the static arrays into local ones - TArray locallist0 = lists[0]; - TArray locallist1 = lists[1]; + TArray locallists[2]; - CollectNode(bsp->children[0], locallist0); - CollectNode(bsp->children[1], locallist1); + for(int l=0;l<2;l++) + { + for (unsigned i=0;ichildren[0], locallists[0]); + CollectNode(bsp->children[1], locallists[1]); } } else { // we reached a subsector so we can link the node with this subsector subsector_t *sub = (subsector_t *)((BYTE *)node - 1); - - CollectSubsector(sub, shape); + collect.Push(int(sub-subsectors)); } } }; @@ -515,14 +442,7 @@ void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, F build.center.x = xs_CRoundToInt(centerx / subsector->numlines); build.center.y = xs_CRoundToInt(centery / subsector->numlines); - if (numnodes == 0) - { - build.CollectSubsector (subsectors, shape); - } - else - { - build.CollectNode(nodes + numnodes - 1, shape); - } + build.CollectNode(nodes + numnodes - 1, shape); coverage->subsectors = new DWORD[build.collect.Size()]; coverage->sscount = build.collect.Size(); memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(DWORD)); @@ -536,13 +456,19 @@ void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, F void gl_InitPortals() { - glcycle_t tpt; - tpt.Reset(); - tpt.Clock(); - TThinkerIterator it; AStackPoint *pt; + if (numnodes == 0) return; + + for(int i=0;idx; + double fdy = (double)no->dy; + no->len = (float)sqrt(fdx * fdx + fdy * fdy); + } + portals.Clear(); while ((pt = it.Next())) { @@ -594,8 +520,6 @@ void gl_InitPortals() portal->ClipAngles.Resize(portal->Shape.Size()); } } - tpt.Unclock(); - Printf("Portal init took %f ms\n", tpt.TimeMS()); } From b698a4cbd4bcf3bbdc023a453a10df7d216caa4c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 11 Nov 2010 11:02:40 +0000 Subject: [PATCH 26/82] - created a branch to do some tests with the portal coverage information. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1085 b0f79afe-0144-0410-b225-9a4edf0717df From b6714bcc3f0b3e0d0b8c39fd594b41375173a393 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 12 Nov 2010 00:32:07 +0000 Subject: [PATCH 27/82] Initial changes for portal coverage: - add portal coverage data to drawinfo. - create portal coverage on the fly for subsectors that get added to a portal by visplane merging. - if BSP traversal enters a subsector that is marked as 'seen' remove its clipping range from the clipper so that its lines (and everything behind it) will be rendered. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1086 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.h | 2 +- src/gl/renderer/gl_renderer.h | 11 +++---- src/gl/scene/gl_bsp.cpp | 52 ++++++++++++++++++++++++++++----- src/gl/scene/gl_drawinfo.cpp | 2 ++ src/gl/scene/gl_drawinfo.h | 7 +++++ src/gl/scene/gl_renderhacks.cpp | 28 +++++++++++++----- 6 files changed, 82 insertions(+), 20 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index f2b02468..a8b41c71 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -47,6 +47,6 @@ struct FPortal extern TArray portals; void gl_InitPortals(); - +void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal); #endif diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 9060331f..594ddfc9 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -20,11 +20,12 @@ extern int extralight; enum SectorRenderFlags { // This is used to avoid creating too many drawinfos - SSRF_RENDERFLOOR=1, - SSRF_RENDERCEILING=2, - SSRF_RENDER3DPLANES=4, - SSRF_RENDERALL=7, - SSRF_PROCESSED=8, + SSRF_RENDERFLOOR = 1, + SSRF_RENDERCEILING = 2, + SSRF_RENDER3DPLANES = 4, + SSRF_RENDERALL = 7, + SSRF_PROCESSED = 8, + SSRF_SEEN = 16, }; struct GL_IRECT diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index d6e8dfc5..3566879f 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -62,6 +62,26 @@ CVAR(Bool, gl_render_things, true, 0) CVAR(Bool, gl_render_walls, true, 0) CVAR(Bool, gl_render_flats, true, 0) + +static void UnclipSubsector(subsector_t *sub) +{ + int count = sub->numlines; + seg_t * seg = sub->firstline; + + while (count--) + { + angle_t startAngle = seg->v2->GetClipAngle(); + angle_t endAngle = seg->v1->GetClipAngle(); + + // Back side, i.e. backface culling - read: endAngle >= startAngle! + if (startAngle-endAngle >= ANGLE_180) + { + clipper.SafeRemoveClipRange(startAngle, endAngle); + } + seg++; + } +} + //========================================================================== // // R_AddLine @@ -367,6 +387,14 @@ static void DoSubsector(subsector_t * sub) sector=sub->sector; if (!sector) return; + if (gl_drawinfo->ss_renderflags[sub-subsectors] & SSRF_SEEN) + { + // This means that we have reached a subsector in a portal that has been marked 'seen' + // from the other side of the portal. This means we must clear the clipper for the + // range this subsector spans before going on. + UnclipSubsector(sub); + } + fakesector=gl_FakeFlat(sector, &fake, false); if (sector->validcount != validcount) @@ -426,6 +454,14 @@ static void DoSubsector(subsector_t * sub) // Due to the way a BSP works such a subsector can never be visible if (!sector->heightsec || sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC || in_area!=area_default) { + if (sector != sub->render_sector) + { + sector = sub->render_sector; + // the planes of this subsector are faked to belong to another sector + // This means we need the heightsec parts and light info of the render sector, not the actual one. + fakesector = gl_FakeFlat(sector, &fake, false); + } + BYTE &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum]; if (!(srf & SSRF_PROCESSED)) { @@ -434,13 +470,6 @@ static void DoSubsector(subsector_t * sub) SetupFlat.Clock(); //if (!gl_multithreading) { - if (sector != sub->render_sector) - { - sector = sub->render_sector; - // the planes of this subsector are faked to belong to another sector - // This means we need the heightsec parts and light info of the render sector, not the actual one! - fakesector = gl_FakeFlat(sector, &fake, false); - } GLRenderer->ProcessSector(fakesector); } /* @@ -456,6 +485,15 @@ static void DoSubsector(subsector_t * sub) gl_drawinfo->ss_renderflags[sub-subsectors] = (sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED; if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub); + + if (fakesector->CeilingSkyBox && fakesector->CeilingSkyBox->bAlways) + { + gl_drawinfo->PortalCoverage[fakesector->CeilingSkyBox->special1].subs.Push(DWORD(sub-subsectors)); + } + if (fakesector->FloorSkyBox && fakesector->FloorSkyBox->bAlways && fakesector->FloorSkyBox != fakesector->CeilingSkyBox) + { + gl_drawinfo->PortalCoverage[fakesector->FloorSkyBox->special1].subs.Push(DWORD(sub-subsectors)); + } } } } diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 0a1b435b..4e818855 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -44,6 +44,7 @@ #include "r_main.h" #include "gl/system/gl_cvars.h" +#include "gl/data/gl_data.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/dynlights/gl_lightbuffer.h" @@ -939,6 +940,7 @@ void FDrawInfo::StartScene() sectorrenderflags.Resize(numsectors); ss_renderflags.Resize(numsubsectors); + PortalCoverage.Resize(portals.Size()); memset(§orrenderflags[0], 0, numsectors*sizeof(sectorrenderflags[0])); memset(&ss_renderflags[0], 0, numsubsectors*sizeof(ss_renderflags[0])); diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index f669b3aa..63da3bca 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -189,6 +189,11 @@ struct FDrawInfo BYTE flags; }; + struct FPortalCoverageInfo + { + TArray subs; + }; + TArray sectorrenderflags; TArray ss_renderflags; @@ -208,6 +213,8 @@ struct FDrawInfo TArray HandledSubsectors; + TArray PortalCoverage; + FDrawInfo * next; GLDrawList drawlists[GLDL_TYPES]; diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index c03b9186..9035e840 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -1173,12 +1173,19 @@ void FDrawInfo::ProcessSectorStacks() } for(unsigned int j=0;jportalcoverage[sector_t::ceiling].subsectors == NULL) + { + gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], + sub, &portals[sec->CeilingSkyBox->special1]); + } + PortalCoverage[sec->CeilingSkyBox->special1].subs.Push(DWORD(sub-subsectors)); - if (sub->render_sector->GetAlpha(sector_t::ceiling)!=0) + if (sec->GetAlpha(sector_t::ceiling) != 0) { gl_subsectorrendernode * node = SSR_List.GetNew(); - node->sub = HandledSubsectors[j]; + node->sub = sub; AddOtherCeilingPlane(sub->render_sector->sectornum, node); } } @@ -1209,13 +1216,20 @@ void FDrawInfo::ProcessSectorStacks() for(unsigned int j=0;jrender_sector->sectornum); - ss_renderflags[DWORD(HandledSubsectors[j]-subsectors)] &= ~SSRF_RENDERFLOOR; + subsector_t *sub = HandledSubsectors[j]; + ss_renderflags[DWORD(sub-subsectors)] &= ~SSRF_RENDERFLOOR; - if (sub->render_sector->GetAlpha(sector_t::floor)!=0) + if (sub->portalcoverage[sector_t::floor].subsectors == NULL) + { + gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], + sub, &portals[sec->FloorSkyBox->special1]); + } + PortalCoverage[sec->FloorSkyBox->special1].subs.Push(DWORD(sub-subsectors)); + + if (sec->GetAlpha(sector_t::floor)!=0) { gl_subsectorrendernode * node = SSR_List.GetNew(); - node->sub = HandledSubsectors[j]; + node->sub = sub; AddOtherFloorPlane(sub->render_sector->sectornum, node); } } From ae052c72009fb2f22cb7a14a6d1c80d3b7e2ddb9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 12 Nov 2010 08:00:44 +0000 Subject: [PATCH 28/82] - add a silhouette to the clipper. This is a range of clip nodes that cannot be removed. Used to lock out parts permanently that will never be visible in a portal. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1087 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_clipper.cpp | 64 +++++++++++++++++++++++++++++++++++++ src/gl/scene/gl_clipper.h | 3 ++ src/gl/scene/gl_portal.cpp | 2 ++ 3 files changed, 69 insertions(+) diff --git a/src/gl/scene/gl_clipper.cpp b/src/gl/scene/gl_clipper.cpp index 1d162044..afcd11bf 100644 --- a/src/gl/scene/gl_clipper.cpp +++ b/src/gl/scene/gl_clipper.cpp @@ -93,6 +93,14 @@ void Clipper::Clear() ClipNode *node = cliphead; ClipNode *temp; + while (node != NULL) + { + temp = node; + node = node->next; + temp->Free(); + } + node = silhouette; + while (node != NULL) { temp = node; @@ -101,9 +109,33 @@ void Clipper::Clear() } cliphead = NULL; + silhouette = NULL; anglecache++; } +//----------------------------------------------------------------------------- +// +// SetSilhouette +// +//----------------------------------------------------------------------------- + +void Clipper::SetSilhouette() +{ + ClipNode *node = cliphead; + ClipNode *last = NULL; + + while (node != NULL) + { + ClipNode *snode = new ClipNode; + snode->start = node->start; + snode->end = node->end; + snode->prev = last; + snode->next = NULL; + if (last != NULL) last->next = snode; + node = node->next; + } +} + //----------------------------------------------------------------------------- // @@ -244,7 +276,39 @@ void Clipper::AddClipRange(angle_t start, angle_t end) void Clipper::RemoveClipRange(angle_t start, angle_t end) { ClipNode *node, *temp; + + if (silhouette) + { + node = silhouette; + while (node != NULL && node->end <= start) + { + node = node->next; + } + if (node->start <= start) + { + if (node->end >= end) return; + start = node->end; + node = node->next; + } + while (node->start < end) + { + DoRemoveClipRange(start, node->start); + start = node->end; + node = node->next; + } + if (start >= end) return; + } + DoRemoveClipRange(start, end); +} +//----------------------------------------------------------------------------- +// +// RemoveClipRange worker function +// +//----------------------------------------------------------------------------- + +void Clipper::DoRemoveClipRange(angle_t start, angle_t end) +{ if (cliphead) { //check to see if range contains any old ranges diff --git a/src/gl/scene/gl_clipper.h b/src/gl/scene/gl_clipper.h index 4ad5c1b9..7139c9d6 100644 --- a/src/gl/scene/gl_clipper.h +++ b/src/gl/scene/gl_clipper.h @@ -51,12 +51,14 @@ class Clipper { ClipNode * clipnodes; ClipNode * cliphead; + ClipNode * silhouette; // will be preserved even when RemoveClipRange is called static angle_t AngleToPseudo(angle_t ang); bool IsRangeVisible(angle_t startangle, angle_t endangle); void RemoveRange(ClipNode * cn); void AddClipRange(angle_t startangle, angle_t endangle); void RemoveClipRange(angle_t startangle, angle_t endangle); + void DoRemoveClipRange(angle_t start, angle_t end); public: @@ -72,6 +74,7 @@ public: void Clear(); + void SetSilhouette(); bool SafeCheckRange(angle_t startAngle, angle_t endAngle) { diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 5c068856..4c7b7ec0 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -325,6 +325,8 @@ inline void GLPortal::ClearClipper() angle_t a1 = GLRenderer->FrustumAngle(); if (a1 Date: Fri, 12 Nov 2010 08:12:24 +0000 Subject: [PATCH 29/82] - removed unused bounding box from subsector struct. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1088 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_setup.cpp | 15 --------------- src/gl/scene/gl_clipper.cpp | 4 +++- src/r_defs.h | 2 +- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index dd1d3f1d..bebaccc5 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -150,24 +150,9 @@ static void SpreadHackedFlag(subsector_t * sub) static void PrepareSectorData() { int i; - size_t /*ii,*/ jj; TArray undetermined; subsector_t * ss; - // look up sector number for each subsector - for (i = 0; i < numsubsectors; i++) - { - ss = &subsectors[i]; - seg_t *seg = ss->firstline; - - M_ClearBox(ss->bbox); - for(jj=0; jjnumlines; jj++) - { - M_AddToBox(ss->bbox,seg->v1->x, seg->v1->y); - seg++; - } - } - // now group the subsectors by sector subsector_t ** subsectorbuffer = new subsector_t * [numsubsectors]; diff --git a/src/gl/scene/gl_clipper.cpp b/src/gl/scene/gl_clipper.cpp index afcd11bf..3759b9f4 100644 --- a/src/gl/scene/gl_clipper.cpp +++ b/src/gl/scene/gl_clipper.cpp @@ -275,7 +275,7 @@ void Clipper::AddClipRange(angle_t start, angle_t end) void Clipper::RemoveClipRange(angle_t start, angle_t end) { - ClipNode *node, *temp; + ClipNode *node; if (silhouette) { @@ -309,6 +309,8 @@ void Clipper::RemoveClipRange(angle_t start, angle_t end) void Clipper::DoRemoveClipRange(angle_t start, angle_t end) { + ClipNode *node, *temp; + if (cliphead) { //check to see if range contains any old ranges diff --git a/src/r_defs.h b/src/r_defs.h index e4f93684..48b14718 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1069,8 +1069,8 @@ struct subsector_t // subsector related GL data FLightNode * lighthead[2]; // Light nodes (blended and additive) - fixed_t bbox[4]; // Bounding box int validcount; + short mapsection; char hacked; // 1: is part of a render hack // 2: has one-sided walls FPortalCoverage portalcoverage[2]; From 7182167785a8f33d1c1dc108054e99ab69fb8b26 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 12 Nov 2010 10:54:12 +0000 Subject: [PATCH 30/82] - fixed: The silhouette builder did not link its nodes. - added a map section property to subsectors. A map section is a continuous part of the map. This is used to exclude separated parts of the map that can never be seen from the current viewpoint from getting rendered. - removed unused bounding box utility functions. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1089 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.h | 1 + src/gl/data/gl_setup.cpp | 111 ++++++++++++++++++++++++++++++------ src/gl/scene/gl_bsp.cpp | 3 + src/gl/scene/gl_clipper.cpp | 7 +-- src/gl/scene/gl_portal.cpp | 24 +++++++- src/gl/scene/gl_portal.h | 1 + src/gl/scene/gl_scene.cpp | 4 ++ 7 files changed, 130 insertions(+), 21 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index a8b41c71..6ac383dc 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -45,6 +45,7 @@ struct FPortal }; extern TArray portals; +extern TArray currentmapsection; void gl_InitPortals(); void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal); diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index bebaccc5..cf20203d 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -103,6 +103,62 @@ void gl_InitSegs() } } +//========================================================================== +// +// +// +//========================================================================== + +static void DoSetMapSection(subsector_t *sub, int num) +{ + sub->mapsection = num; + + for(DWORD i=0;inumlines;i++) + { + seg_t * seg = sub->firstline + i; + + if (seg->PartnerSeg) + { + subsector_t * sub2 = seg->PartnerSeg->Subsector(); + + if (sub2->mapsection != num) + { + assert(sub2->mapsection == 0); + DoSetMapSection(sub2, num); + } + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +static void SetMapSections() +{ + bool set; + int num = 0; + do + { + set = false; + for(int i=0; ibox[BOXRIGHT]) box[BOXRIGHT] = x; - if (ybox[BOXTOP]) box[BOXTOP] = y; -} - static void SpreadHackedFlag(subsector_t * sub) { // The subsector pointer hasn't been set yet! @@ -147,6 +189,12 @@ static void SpreadHackedFlag(subsector_t * sub) } +//========================================================================== +// +// +// +//========================================================================== + static void PrepareSectorData() { int i; @@ -193,6 +241,7 @@ static void PrepareSectorData() } } } + SetMapSections(); } //========================================================================== @@ -201,6 +250,7 @@ static void PrepareSectorData() // - This will be used to lower the floor of such sectors by one map unit // //========================================================================== + static void PrepareTransparentDoors(sector_t * sector) { bool solidwall=false; @@ -285,12 +335,12 @@ static void PrepareTransparentDoors(sector_t * sector) } } - //========================================================================== // // // //========================================================================== + static void AddToVertex(const sector_t * sec, TArray & list) { int secno = int(sec-sectors); @@ -307,6 +357,7 @@ static void AddToVertex(const sector_t * sec, TArray & list) // Attach sectors to vertices - used to generate vertex height lists // //========================================================================== + static void InitVertexData() { TArray * vt_sectorlists; @@ -376,7 +427,7 @@ static void InitVertexData() //========================================================================== // -// Group segs to sidedefs +// // //========================================================================== @@ -406,6 +457,12 @@ static int STACK_ARGS segcmp(const void *a, const void *b) return xs_RoundToInt(FRACUNIT*(A->sidefrac - B->sidefrac)); } +//========================================================================== +// +// Group segs to sidedefs +// +//========================================================================== + static void PrepareSegs() { int *segcount = new int[numsides]; @@ -533,6 +590,7 @@ void gl_PreprocessLevel() // Cleans up all the GL data for the last level // //========================================================================== + void gl_CleanLevelData() { // Dynamic lights must be destroyed before the sector information here is deleted. @@ -585,3 +643,24 @@ void gl_CleanLevelData() } } + +//========================================================================== +// +// +// +//========================================================================== + +CCMD(listmapsections) +{ + for(int i=0;i<100;i++) + { + for (int j=0;jsectornum, int(subsectors[j].firstline->linedef-lines)); + break; + } + } + } +} \ No newline at end of file diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 3566879f..56ac480b 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -387,6 +387,9 @@ static void DoSubsector(subsector_t * sub) sector=sub->sector; if (!sector) return; + // If the mapsections differ this subsector can't possibly be visible from the current view point + if (!(currentmapsection[sub->mapsection>>3] & (1 << (sub->mapsection & 7)))) return; + if (gl_drawinfo->ss_renderflags[sub-subsectors] & SSRF_SEEN) { // This means that we have reached a subsector in a portal that has been marked 'seen' diff --git a/src/gl/scene/gl_clipper.cpp b/src/gl/scene/gl_clipper.cpp index 3759b9f4..3c271f5f 100644 --- a/src/gl/scene/gl_clipper.cpp +++ b/src/gl/scene/gl_clipper.cpp @@ -126,12 +126,11 @@ void Clipper::SetSilhouette() while (node != NULL) { - ClipNode *snode = new ClipNode; - snode->start = node->start; - snode->end = node->end; + ClipNode *snode = ClipNode::NewRange(node->start, node->end); + if (silhouette == NULL) silhouette = snode; snode->prev = last; - snode->next = NULL; if (last != NULL) last->next = snode; + last = snode; node = node->next; } } diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 4c7b7ec0..de6a7c21 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -613,6 +613,11 @@ void GLSkyboxPortal::DrawContents() GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); GLRenderer->SetViewArea(); ClearClipper(); + + int mapsection = R_PointInSubsector(viewx, viewy)->mapsection; + memset(¤tmapsection[0], 0, currentmapsection.Size()); + currentmapsection[mapsection>>3] |= 1 << (mapsection & 7); + GLRenderer->DrawScene(); origin->flags&=~MF_JUSTHIT; inskybox=false; @@ -742,6 +747,24 @@ int GLSectorStackPortal::ClipSeg(seg_t *seg) #endif } +//----------------------------------------------------------------------------- +// +// GLSectorStackPortal::SetupCoverage +// +//----------------------------------------------------------------------------- + +/* +void GLSectorStackPortal::SetupCoverage() +{ + memset(¤tmapsection[0], 0, currentmapsection.Size()); + + FPortalCoverageInfo *pc = &gl_drawinfo->PortalCoverage[origin->origin->special1]; + for(unsigned i = 0; i < pc->subs.Size(); i++) + { + subsector_t *sub = &subsectors[pc->subs[i]; +} +*/ + //----------------------------------------------------------------------------- // @@ -783,7 +806,6 @@ int GLSectorStackPortal::ClipPoint(fixed_t x, fixed_t y) return PClip_Inside; } - //----------------------------------------------------------------------------- // // GLPlaneMirrorPortal::DrawContents diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 9767c5fc..c9bbdb59 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -256,6 +256,7 @@ public: } int ClipSeg(seg_t *seg); int ClipPoint(fixed_t x, fixed_t y); + void SetupCoverage(); }; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 9fdc9802..0d9ae6d4 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -91,6 +91,7 @@ extern int viewpitch; DWORD gl_fixedcolormap; area_t in_area; +TArray currentmapsection; void R_SetupFrame (AActor * camera); @@ -847,6 +848,9 @@ void FGLRenderer::ProcessScene(bool toscreen) iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; GLPortal::BeginScene(); + int mapsection = R_PointInSubsector(viewx, viewy)->mapsection; + memset(¤tmapsection[0], 0, currentmapsection.Size()); + currentmapsection[mapsection>>3] |= 1 << (mapsection & 7); DrawScene(toscreen); FDrawInfo::EndDrawInfo(); From 68952917c2f402a7807e6b2c63d55be7420a839f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 12 Nov 2010 14:11:17 +0000 Subject: [PATCH 31/82] - implemented usage of coverage info for portal clipping. - removed some obsolete data structures use for maintaining portals. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1090 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.h | 16 ++++++ src/gl/data/gl_portaldata.cpp | 88 ++++++++++++++++++--------------- src/gl/scene/gl_bsp.cpp | 16 ++++-- src/gl/scene/gl_clipper.cpp | 4 +- src/gl/scene/gl_drawinfo.cpp | 1 - src/gl/scene/gl_drawinfo.h | 7 --- src/gl/scene/gl_portal.cpp | 27 +++++----- src/gl/scene/gl_portal.h | 18 +++---- src/gl/scene/gl_renderhacks.cpp | 28 ++++++++--- src/gl/scene/gl_scene.cpp | 1 + src/gl/scene/gl_sky.cpp | 17 ++++--- src/gl/scene/gl_wall.h | 4 +- src/gl/scene/gl_walls.cpp | 4 +- 13 files changed, 137 insertions(+), 94 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index 6ac383dc..043fab3d 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -28,6 +28,7 @@ void gl_RecalcVertexHeights(vertex_t * v); FTextureID gl_GetSpriteFrame(unsigned sprite, int frame, int rot, angle_t ang, bool *mirror); class AStackPoint; +struct GLSectorStackPortal; struct FPortal { @@ -37,16 +38,31 @@ struct FPortal fixed_t yDisplacement; int plane; AStackPoint *origin; + GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! int PointOnShapeLineSide(fixed_t x, fixed_t y, int shapeindex); void AddVertexToShape(vertex_t *vertex); void AddSectorToPortal(sector_t *sector); void UpdateClipAngles(); + GLSectorStackPortal *GetGLPortal(); }; extern TArray portals; extern TArray currentmapsection; +inline FPortal *gl_GetPortal(AActor *pt, int plane) +{ + if (plane == sector_t::floor) + { + if (pt->special1 != -1) return &portals[pt->special1]; + } + else + { + if (pt->special2 != -1) return &portals[pt->special2]; + } + return NULL; +} + void gl_InitPortals(); void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal); diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index cb40d6a8..1c7b26ee 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -57,6 +57,7 @@ #include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_clipper.h" +#include "gl/scene/gl_portal.h" #include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_glow.h" #include "gl/utility/gl_clock.h" @@ -203,7 +204,17 @@ void FPortal::UpdateClipAngles() } } +//========================================================================== +// +// +// +//========================================================================== +GLSectorStackPortal *FPortal::GetGLPortal() +{ + if (glportal == NULL) glportal = new GLSectorStackPortal(this); + return glportal; +} //========================================================================== // @@ -472,53 +483,52 @@ void gl_InitPortals() portals.Clear(); while ((pt = it.Next())) { - FPortal *portal = NULL; - int plane; + FPortal *portalp[2] = {NULL, NULL}; pt->special1 = -1; + pt->special2 = -1; for(int i=0;i &p = plane==1? sectors[i].CeilingSkyBox : sectors[i].FloorSkyBox; + if (p != pt) continue; - // we only process portals that actually are in use. - if (portal == NULL) - { - pt->special1 = portals.Size(); // Link portal thing to render data - portal = &portals[portals.Reserve(1)]; - portal->origin = pt; - portal->plane = 0; - portal->xDisplacement = pt->x - pt->Mate->x; - portal->yDisplacement = pt->y - pt->Mate->y; - } - portal->AddSectorToPortal(§ors[i]); - portal->plane|=plane; + // we only process portals that actually are in use. + if (portalp[plane] == NULL) + { + if (plane==0) pt->special1 = portals.Size(); // Link portal thing to render data + else pt->special2 = portals.Size(); // floor goes into special1, ceiling into spacial2 + portalp[plane] = &portals[portals.Reserve(1)]; + portalp[plane]->origin = pt; + portalp[plane]->glportal = NULL; + portalp[plane]->plane = plane; + portalp[plane]->xDisplacement = pt->x - pt->Mate->x; + portalp[plane]->yDisplacement = pt->y - pt->Mate->y; + } + portalp[plane]->AddSectorToPortal(§ors[i]); - for (int j=0;j < sectors[i].subsectorcount; j++) - { - subsector_t *sub = sectors[i].subsectors[j]; - gl_BuildPortalCoverage(&sub->portalcoverage[plane-1], sub, portal); + for (int j=0;j < sectors[i].subsectorcount; j++) + { + subsector_t *sub = sectors[i].subsectors[j]; + gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, portalp[plane]); + } } } - if (portal != NULL) - { - // if the first vertex is duplicated at the end it'll save time in a time critical function - // because that code does not need to check for wraparounds anymore. - portal->Shape.Resize(portal->Shape.Size()+1); - portal->Shape[portal->Shape.Size()-1] = portal->Shape[0]; - portal->Shape.ShrinkToFit(); - portal->ClipAngles.Resize(portal->Shape.Size()); - } + } + + for(unsigned i=0;ix/65536., portals[i].origin->y/65536., + Printf(PRINT_LOG, "Portal #%d, %s, stackpoint at (%f,%f), displacement = (%f,%f)\nShape:\n", i, portals[i].plane==0? "floor":"ceiling", portals[i].origin->x/65536., portals[i].origin->y/65536., xdisp, ydisp); for (unsigned j=0;jrender_sector->FloorSkyBox : sub->render_sector->CeilingSkyBox; - if (pt != NULL && pt->bAlways && pt->special1 == i) + ASkyViewpoint *pt = portals[i].plane == 0? sub->render_sector->FloorSkyBox : sub->render_sector->CeilingSkyBox; + if (pt == portals[i].origin) { Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", j, sub->render_sector->sectornum); for(unsigned k = 0;k< sub->numlines; k++) @@ -548,7 +558,7 @@ CCMD(dumpportals) Printf(PRINT_LOG, "(%.3f,%.3f), ", sub->firstline[k].v1->x/65536. + xdisp, sub->firstline[k].v1->y/65536. + ydisp); } Printf(PRINT_LOG, "\n\t\tCovered by subsectors:\n"); - FPortalCoverage *cov = &sub->portalcoverage[portals[i].plane-1]; + FPortalCoverage *cov = &sub->portalcoverage[portals[i].plane]; for(int l = 0;l< cov->sscount; l++) { subsector_t *csub = &subsectors[cov->subsectors[l]]; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 56ac480b..fbe914d2 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -491,11 +491,21 @@ static void DoSubsector(subsector_t * sub) if (fakesector->CeilingSkyBox && fakesector->CeilingSkyBox->bAlways) { - gl_drawinfo->PortalCoverage[fakesector->CeilingSkyBox->special1].subs.Push(DWORD(sub-subsectors)); + FPortal *portal = gl_GetPortal(fakesector->CeilingSkyBox, sector_t::ceiling); + if (portal != NULL) + { + GLSectorStackPortal *glportal = portal->GetGLPortal(); + glportal->AddSubsector(sub); + } } - if (fakesector->FloorSkyBox && fakesector->FloorSkyBox->bAlways && fakesector->FloorSkyBox != fakesector->CeilingSkyBox) + if (fakesector->FloorSkyBox && fakesector->FloorSkyBox->bAlways) { - gl_drawinfo->PortalCoverage[fakesector->FloorSkyBox->special1].subs.Push(DWORD(sub-subsectors)); + FPortal *portal = gl_GetPortal(fakesector->FloorSkyBox, sector_t::floor); + if (portal != NULL) + { + GLSectorStackPortal *glportal = portal->GetGLPortal(); + glportal->AddSubsector(sub); + } } } } diff --git a/src/gl/scene/gl_clipper.cpp b/src/gl/scene/gl_clipper.cpp index 3c271f5f..bde49029 100644 --- a/src/gl/scene/gl_clipper.cpp +++ b/src/gl/scene/gl_clipper.cpp @@ -283,13 +283,13 @@ void Clipper::RemoveClipRange(angle_t start, angle_t end) { node = node->next; } - if (node->start <= start) + if (node != NULL && node->start <= start) { if (node->end >= end) return; start = node->end; node = node->next; } - while (node->start < end) + while (node != NULL && node->start < end) { DoRemoveClipRange(start, node->start); start = node->end; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 4e818855..1e52399d 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -940,7 +940,6 @@ void FDrawInfo::StartScene() sectorrenderflags.Resize(numsectors); ss_renderflags.Resize(numsubsectors); - PortalCoverage.Resize(portals.Size()); memset(§orrenderflags[0], 0, numsectors*sizeof(sectorrenderflags[0])); memset(&ss_renderflags[0], 0, numsubsectors*sizeof(ss_renderflags[0])); diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 63da3bca..f669b3aa 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -189,11 +189,6 @@ struct FDrawInfo BYTE flags; }; - struct FPortalCoverageInfo - { - TArray subs; - }; - TArray sectorrenderflags; TArray ss_renderflags; @@ -213,8 +208,6 @@ struct FDrawInfo TArray HandledSubsectors; - TArray PortalCoverage; - FDrawInfo * next; GLDrawList drawlists[GLDL_TYPES]; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index de6a7c21..01ec552b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -89,7 +89,6 @@ bool GLPortal::inskybox; UniqueList UniqueSkies; UniqueList UniqueHorizons; -UniqueList UniqueStacks; UniqueList UniquePlaneMirrors; @@ -104,7 +103,6 @@ void GLPortal::BeginScene() { UniqueSkies.Clear(); UniqueHorizons.Clear(); - UniqueStacks.Clear(); UniquePlaneMirrors.Clear(); } @@ -635,7 +633,7 @@ void GLSkyboxPortal::DrawContents() //----------------------------------------------------------------------------- void GLSectorStackPortal::DrawContents() { - FPortal *portal = &::portals[origin->origin->special1]; + FPortal *portal = origin; portal->UpdateClipAngles(); viewx += origin->origin->x - origin->origin->Mate->x; @@ -647,10 +645,11 @@ void GLSectorStackPortal::DrawContents() validcount++; // avoid recursions! - if (origin->isupper) inupperstack=true; + if (origin->plane == sector_t::ceiling) inupperstack=true; else inlowerstack=true; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); + SetupCoverage(); ClearClipper(); GLRenderer->DrawScene(); } @@ -662,7 +661,7 @@ void GLSectorStackPortal::DrawContents() //----------------------------------------------------------------------------- int GLSectorStackPortal::ClipSeg(seg_t *seg) { - FPortal *portal = &::portals[origin->origin->special1]; + FPortal *portal = origin; angle_t *angles = &portal->ClipAngles[0]; unsigned numpoints = portal->ClipAngles.Size()-1; angle_t clipangle = seg->v1->GetClipAngle(); @@ -753,17 +752,21 @@ int GLSectorStackPortal::ClipSeg(seg_t *seg) // //----------------------------------------------------------------------------- -/* void GLSectorStackPortal::SetupCoverage() { memset(¤tmapsection[0], 0, currentmapsection.Size()); - - FPortalCoverageInfo *pc = &gl_drawinfo->PortalCoverage[origin->origin->special1]; - for(unsigned i = 0; i < pc->subs.Size(); i++) + for(unsigned i=0; isubs[i]; + subsector_t *sub = subsectors[i]; + int plane = origin->plane; + for(int j=0;jportalcoverage[plane].sscount; j++) + { + subsector_t *dsub = &::subsectors[sub->portalcoverage[plane].subsectors[j]]; + currentmapsection[dsub->mapsection>>3] |= 1 << (dsub->mapsection&7); + gl_drawinfo->ss_renderflags[dsub-::subsectors] |= SSRF_SEEN; + } + } } -*/ //----------------------------------------------------------------------------- @@ -773,7 +776,7 @@ void GLSectorStackPortal::SetupCoverage() //----------------------------------------------------------------------------- int GLSectorStackPortal::ClipPoint(fixed_t x, fixed_t y) { - FPortal *portal = &::portals[origin->origin->special1]; + FPortal *portal = origin; angle_t *angles = &portal->ClipAngles[0]; unsigned numpoints = portal->ClipAngles.Size()-1; angle_t clipangle = R_PointToPseudoAngle(viewx, viewy, x, y); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index c9bbdb59..f255ad8e 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -72,17 +72,8 @@ struct GLSkyInfo } }; -struct GLSectorStackInfo -{ - ASkyViewpoint *origin; - bool isupper; -}; - - - extern UniqueList UniqueSkies; extern UniqueList UniqueHorizons; -extern UniqueList UniqueStacks; extern UniqueList UniquePlaneMirrors; class GLPortal @@ -241,22 +232,27 @@ public: struct GLSectorStackPortal : public GLPortal { + TArray subsectors; protected: virtual void DrawContents(); virtual void * GetSource() const { return origin; } virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one. virtual const char *GetName(); - GLSectorStackInfo * origin; + FPortal *origin; public: - GLSectorStackPortal(GLSectorStackInfo * pt) + GLSectorStackPortal(FPortal *pt) { origin=pt; } int ClipSeg(seg_t *seg); int ClipPoint(fixed_t x, fixed_t y); void SetupCoverage(); + void AddSubsector(subsector_t *sub) + { + subsectors.Push(sub); + } }; diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index 9035e840..172fdca9 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -49,6 +49,7 @@ #include "gl/dynlights/gl_glow.h" #include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" +#include "gl/scene/gl_portal.h" #include "gl/utility/gl_clock.h" #include "gl/utility/gl_templates.h" @@ -1175,12 +1176,18 @@ void FDrawInfo::ProcessSectorStacks() { subsector_t *sub = HandledSubsectors[j]; ss_renderflags[DWORD(sub-subsectors)] &= ~SSRF_RENDERCEILING; - if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) + FPortal *portal = gl_GetPortal(sec->CeilingSkyBox, sector_t::ceiling); + + if (portal != NULL) { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], - sub, &portals[sec->CeilingSkyBox->special1]); + if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) + { + gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal); + } + + GLSectorStackPortal *glportal = portal->GetGLPortal(); + glportal->AddSubsector(sub); } - PortalCoverage[sec->CeilingSkyBox->special1].subs.Push(DWORD(sub-subsectors)); if (sec->GetAlpha(sector_t::ceiling) != 0) { @@ -1219,12 +1226,17 @@ void FDrawInfo::ProcessSectorStacks() subsector_t *sub = HandledSubsectors[j]; ss_renderflags[DWORD(sub-subsectors)] &= ~SSRF_RENDERFLOOR; - if (sub->portalcoverage[sector_t::floor].subsectors == NULL) + FPortal *portal = gl_GetPortal(sec->FloorSkyBox, sector_t::floor); + if (portal != NULL) { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], - sub, &portals[sec->FloorSkyBox->special1]); + if (sub->portalcoverage[sector_t::floor].subsectors == NULL) + { + gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal); + } + + GLSectorStackPortal *glportal = portal->GetGLPortal(); + glportal->AddSubsector(sub); } - PortalCoverage[sec->FloorSkyBox->special1].subs.Push(DWORD(sub-subsectors)); if (sec->GetAlpha(sector_t::floor)!=0) { diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 0d9ae6d4..96e66e07 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -851,6 +851,7 @@ void FGLRenderer::ProcessScene(bool toscreen) int mapsection = R_PointInSubsector(viewx, viewy)->mapsection; memset(¤tmapsection[0], 0, currentmapsection.Size()); currentmapsection[mapsection>>3] |= 1 << (mapsection & 7); + for(unsigned i=0;iportal->GetGLPortal(); portal->AddLine(this); break; From 073c77400575dd87bdd244d31bcea3b1c967399d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 12 Nov 2010 21:18:25 +0000 Subject: [PATCH 32/82] - fixed midtexture positioning for sectors with a sky ceiling and a heightsec. Update to ZDoom r3008: * Added a hidden compatiblity option for maps that fell victim to the broken destination search code in some 2.0.9x versions * Turns out I can't clear one protocol warning on 10.6 without breaking compatibility with 10.4/10.5. * Fixed: Hexen's frag counter was not placed correctly. * Fixed: Cocoa IWAD picker was not updated. Also changed instances of the deprecated stringWithCString to stringWithUTF8String. * Fixed: Mac OS X should be case insensitive like Windows. * Fixed: Boom's switch-based equivalents of FloorandCeiling_LowerRaise can only move either the ceiling or the floor but never both due to a programming error. Changed this special so that Boom's broken mode can be reactivated through xlat. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1091 b0f79afe-0144-0410-b225-9a4edf0717df --- src/compatibility.cpp | 1 + src/d_iwad.cpp | 2 +- src/doomdef.h | 1 + src/gl/scene/gl_wall.h | 1 + src/gl/scene/gl_walls.cpp | 10 ++++++---- src/p_lnspec.cpp | 14 +++++++++++--- src/p_teleport.cpp | 3 +++ src/sdl/iwadpicker_cocoa.mm | 16 ++++++++-------- src/svnrevision.h | 4 ++-- wadsrc/static/compatibility.txt | 4 ++++ wadsrc/static/sbarinfo/hexen.txt | 2 +- wadsrc/static/xlat/base.txt | 4 ++-- 12 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index ab1c98ca..880f8878 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -89,6 +89,7 @@ static FCompatOption Options[] = { "setslopeoverflow", 0, BCOMPATF_SETSLOPEOVERFLOW }, { "resetplayerspeed", 0, BCOMPATF_RESETPLAYERSPEED }, { "vileghosts", 0, BCOMPATF_VILEGHOSTS }, + { "ignoreteleporttags", 0, BCOMPATF_BADTELEPORTERS }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, 0 }, diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index d03507bf..6fd42a62 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -227,7 +227,7 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize) { sc.MustGetString(); FString wadname = sc.String; -#ifdef _WIN32 +#if defined(_WIN32) || defined(__APPLE__) // Turns out Mac OS X is case insensitive. mIWadNames.Push(wadname); #else // check for lowercase, uppercased first letter and full uppercase on Linux etc. diff --git a/src/doomdef.h b/src/doomdef.h index 9ad019db..cad56d64 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -341,6 +341,7 @@ enum BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' radius and height aren't restored properly when resurrected. + BCOMPATF_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials }; // phares 3/20/98: diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 139d5c21..e1678e8f 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -185,6 +185,7 @@ private: int v_offset); void DoMidTexture(seg_t * seg, bool drawfogboundary, + sector_t * front, sector_t * back, sector_t * realfront, sector_t * realback, fixed_t fch1, fixed_t fch2, fixed_t ffh1, fixed_t ffh2, fixed_t bch1, fixed_t bch2, fixed_t bfh1, fixed_t bfh2); diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 1d33b46a..21d73185 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -785,6 +785,7 @@ void GLWall::DoTexture(int _type,seg_t * seg, int peg, //========================================================================== void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, + sector_t * front, sector_t * back, sector_t * realfront, sector_t * realback, fixed_t fch1, fixed_t fch2, fixed_t ffh1, fixed_t ffh2, fixed_t bch1, fixed_t bch2, fixed_t bfh1, fixed_t bfh2) @@ -837,8 +838,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::top)); if (!tex || tex->UseType==FTexture::TEX_Null) { - if (seg->frontsector->GetTexture(sector_t::ceiling) == skyflatnum && - seg->backsector->GetTexture(sector_t::ceiling) == skyflatnum) + if (front->GetTexture(sector_t::ceiling) == skyflatnum && + back->GetTexture(sector_t::ceiling) == skyflatnum) { // intra-sky lines do not clip the texture at all if there's no upper texture topleft = topright = texturetop; @@ -1445,7 +1446,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) #ifdef _MSC_VER #ifdef _DEBUG - if (seg->linedef-lines==8) + if (seg->linedef-lines==1095) __asm nop #endif #endif @@ -1657,7 +1658,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), true); if (gltexture || drawfogboundary) { - DoMidTexture(seg, drawfogboundary, realfront, realback, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); + DoMidTexture(seg, drawfogboundary, frontsector, backsector, realfront, realback, + fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); } if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size()) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index a7f799c8..ac752017 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1683,10 +1683,18 @@ FUNC(LS_FloorAndCeiling_RaiseByValue) } FUNC(LS_FloorAndCeiling_LowerRaise) -// FloorAndCeiling_LowerRaise (tag, fspeed, cspeed) +// FloorAndCeiling_LowerRaise (tag, fspeed, cspeed, boomemu) { - return EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg2), 0, 0, 0, 0, 0, false) | - EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, 0, false); + bool res = EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg2), 0, 0, 0, 0, 0, false); + // The switch based Boom equivalents of FloorandCeiling_LowerRaise do incorrect checks + // which cause the floor only to move when the ceiling fails to do so. + // To avoid problems with maps that have incorrect args this only uses a + // more or less unintuitive value for the fourth arg to trigger Boom's broken behavior + if (arg3 != 1998 || !res) // (1998 for the year in which Boom was released... :P) + { + res |= EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, 0, false); + } + return res; } FUNC(LS_Elevator_MoveToFloor) diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 8fe870e8..6ba60be0 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -228,6 +228,9 @@ static AActor *SelectTeleDest (int tid, int tag) // behavior is used instead (return the first teleport dest found in a tagged // sector). + // Compatibility hack for some maps that fell victim to a bug in the teleport code in 2.0.9x + if (ib_compatflags & BCOMPATF_BADTELEPORTERS) tag = 0; + if (tid != 0) { NActorIterator iterator (NAME_TeleportDest, tid); diff --git a/src/sdl/iwadpicker_cocoa.mm b/src/sdl/iwadpicker_cocoa.mm index a835c6df..1a1fa8b8 100644 --- a/src/sdl/iwadpicker_cocoa.mm +++ b/src/sdl/iwadpicker_cocoa.mm @@ -48,7 +48,7 @@ enum static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; // Class to convert the IWAD data into a form that Cocoa can use. -@interface IWADTableData : NSObject +@interface IWADTableData : NSObject// { NSMutableArray *data; } @@ -81,8 +81,8 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; filename = wads[i].Path; else filename++; - [record setObject:[NSString stringWithCString:filename] forKey:[NSString stringWithCString:tableHeaders[COLUMN_IWAD]]]; - [record setObject:[NSString stringWithCString:IWADInfos[wads[i].Type].Name] forKey:[NSString stringWithCString:tableHeaders[COLUMN_GAME]]]; + [record setObject:[NSString stringWithUTF8String:filename] forKey:[NSString stringWithUTF8String:tableHeaders[COLUMN_IWAD]]]; + [record setObject:[NSString stringWithUTF8String:wads[i].Name] forKey:[NSString stringWithUTF8String:tableHeaders[COLUMN_GAME]]]; [data addObject:record]; [record release]; } @@ -144,7 +144,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; // little more automated. - (void)makeLabel:(NSTextField *)label:(const char*) str { - [label setStringValue:[NSString stringWithCString:str]]; + [label setStringValue:[NSString stringWithUTF8String:str]]; [label setBezeled:NO]; [label setDrawsBackground:NO]; [label setEditable:NO]; @@ -156,7 +156,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; cancelled = false; app = [NSApplication sharedApplication]; - id windowTitle = [NSString stringWithCString:GAMESIG " " DOTVERSIONSTR ": Select an IWAD to use"]; + id windowTitle = [NSString stringWithUTF8String:GAMESIG " " DOTVERSIONSTR ": Select an IWAD to use"]; NSRect frame = NSMakeRect(0, 0, 440, 450); window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]; @@ -174,7 +174,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; IWADTableData *tableData = [[IWADTableData alloc] init:wads:numwads]; for(int i = 0;i < NUM_COLUMNS;i++) { - NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithCString:tableHeaders[i]]]; + NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithUTF8String:tableHeaders[i]]]; [[column headerCell] setStringValue:[column identifier]]; if(i == 0) [column setMaxWidth:110]; @@ -211,7 +211,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; [[window contentView] addSubview:dontAsk];*/ okButton = [[NSButton alloc] initWithFrame:NSMakeRect(236, 12, 96, 32)]; - [okButton setTitle:[NSString stringWithCString:"OK"]]; + [okButton setTitle:[NSString stringWithUTF8String:"OK"]]; [okButton setBezelStyle:NSRoundedBezelStyle]; [okButton setAction:@selector(buttonPressed:)]; [okButton setTarget:self]; @@ -219,7 +219,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; [[window contentView] addSubview:okButton]; cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(332, 12, 96, 32)]; - [cancelButton setTitle:[NSString stringWithCString:"Cancel"]]; + [cancelButton setTitle:[NSString stringWithUTF8String:"Cancel"]]; [cancelButton setBezelStyle:NSRoundedBezelStyle]; [cancelButton setAction:@selector(buttonPressed:)]; [cancelButton setTarget:self]; diff --git a/src/svnrevision.h b/src/svnrevision.h index 0904ce2e..2a6b13bc 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3001" -#define ZD_SVN_REVISION_NUMBER 3001 +#define ZD_SVN_REVISION_STRING "3008" +#define ZD_SVN_REVISION_NUMBER 3008 diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 98528363..c3a4404a 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -135,3 +135,7 @@ DCE862393CAAA6FF1294FB7056B53057 // UAC Ultra map07: Contains a scroller dependi setlinespecial 391 Sector_CopyScroller 99 6 0 0 0 } +1D9E43988940CCD3555724E15DD8B1AB // Happy Time Circus map01 has bad teleporters +{ + ignoreteleporttags +} diff --git a/wadsrc/static/sbarinfo/hexen.txt b/wadsrc/static/sbarinfo/hexen.txt index f1c29452..635cb650 100644 --- a/wadsrc/static/sbarinfo/hexen.txt +++ b/wadsrc/static/sbarinfo/hexen.txt @@ -59,7 +59,7 @@ statusbar Normal gamemode deathmatch, teamgame { drawimage "KILLS", 38, 163; - drawnumber 3, HUDFONT_RAVEN, untranslated, frags, 58, 163, 1; + drawnumber 3, HUDFONT_RAVEN, untranslated, frags, 65, 176, 1; } else { diff --git a/wadsrc/static/xlat/base.txt b/wadsrc/static/xlat/base.txt index cc287a60..9ffd409d 100644 --- a/wadsrc/static/xlat/base.txt +++ b/wadsrc/static/xlat/base.txt @@ -168,7 +168,7 @@ include "xlat/defines.i" 163 = USE, Plat_Stop (tag) 164 = USE, Ceiling_CrushAndRaiseA (tag, C_NORMAL, C_NORMAL, 10) 165 = USE, Ceiling_CrushAndRaiseSilentA (tag, C_SLOW, C_SLOW, 10) -166 = USE, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW) +166 = USE, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW, 1998) 167 = USE, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2) 168 = USE, Ceiling_CrushStop (tag) 169 = USE, Light_MaxNeighbor (tag) @@ -188,7 +188,7 @@ include "xlat/defines.i" 183 = USE|REP, Ceiling_CrushAndRaiseA (tag, C_NORMAL, C_NORMAL, 10) 184 = USE|REP, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) 185 = USE|REP, Ceiling_CrushAndRaiseSilentA (tag, C_SLOW, C_SLOW, 10) -186 = USE|REP, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW) +186 = USE|REP, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW, 1998) 187 = USE|REP, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2) 188 = USE|REP, Ceiling_CrushStop (tag) 189 = USE, Floor_TransferTrigger (tag) From 9c5e3de23f9e5e4548dd1d6d91c6c23ded1be6ee Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 13 Nov 2010 13:55:53 +0000 Subject: [PATCH 33/82] - added direct portal references to sectors and use these exclusively when processing portals. The skybox things now only get used for real skyboxes, nothing else. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1092 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.h | 14 +-- src/gl/data/gl_portaldata.cpp | 5 +- src/gl/scene/gl_bsp.cpp | 32 ++--- src/gl/scene/gl_fakeflat.cpp | 10 +- src/gl/scene/gl_flats.cpp | 25 +++- src/gl/scene/gl_renderhacks.cpp | 41 +++--- src/gl/scene/gl_sky.cpp | 212 ++++++++++++++++++-------------- src/gl/scene/gl_wall.h | 2 +- src/gl/scene/gl_walls.cpp | 9 +- src/r_defs.h | 2 + 10 files changed, 189 insertions(+), 163 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index 043fab3d..6d17a06a 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -23,6 +23,7 @@ struct GLRenderSettings extern GLRenderSettings glset; #include "r_defs.h" +#include "a_sharedglobal.h" void gl_RecalcVertexHeights(vertex_t * v); FTextureID gl_GetSpriteFrame(unsigned sprite, int frame, int rot, angle_t ang, bool *mirror); @@ -50,19 +51,6 @@ struct FPortal extern TArray portals; extern TArray currentmapsection; -inline FPortal *gl_GetPortal(AActor *pt, int plane) -{ - if (plane == sector_t::floor) - { - if (pt->special1 != -1) return &portals[pt->special1]; - } - else - { - if (pt->special2 != -1) return &portals[pt->special2]; - } - return NULL; -} - void gl_InitPortals(); void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal); diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index 1c7b26ee..3b1d75c6 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -484,8 +484,6 @@ void gl_InitPortals() while ((pt = it.Next())) { FPortal *portalp[2] = {NULL, NULL}; - pt->special1 = -1; - pt->special2 = -1; for(int i=0;ispecial1 = portals.Size(); // Link portal thing to render data - else pt->special2 = portals.Size(); // floor goes into special1, ceiling into spacial2 portalp[plane] = &portals[portals.Reserve(1)]; portalp[plane]->origin = pt; portalp[plane]->glportal = NULL; @@ -510,6 +506,7 @@ void gl_InitPortals() portalp[plane]->yDisplacement = pt->y - pt->Mate->y; } portalp[plane]->AddSectorToPortal(§ors[i]); + sectors[i].portals[plane] = portalp[plane]; for (int j=0;j < sectors[i].subsectorcount; j++) { diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index fbe914d2..4198b9c7 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -96,6 +96,13 @@ static sector_t *currentsector; static void AddLine (seg_t *seg) { +#ifdef _MSC_VER +#ifdef _DEBUG + if (seg->linedef-lines==38) + __asm nop +#endif +#endif + angle_t startAngle, endAngle; sector_t * backsector = NULL; sector_t bs; @@ -489,23 +496,20 @@ static void DoSubsector(subsector_t * sub) (sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED; if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub); - if (fakesector->CeilingSkyBox && fakesector->CeilingSkyBox->bAlways) + FPortal *portal; + + portal = fakesector->portals[sector_t::ceiling]; + if (portal != NULL) { - FPortal *portal = gl_GetPortal(fakesector->CeilingSkyBox, sector_t::ceiling); - if (portal != NULL) - { - GLSectorStackPortal *glportal = portal->GetGLPortal(); - glportal->AddSubsector(sub); - } + GLSectorStackPortal *glportal = portal->GetGLPortal(); + glportal->AddSubsector(sub); } - if (fakesector->FloorSkyBox && fakesector->FloorSkyBox->bAlways) + + portal = fakesector->portals[sector_t::floor]; + if (portal != NULL) { - FPortal *portal = gl_GetPortal(fakesector->FloorSkyBox, sector_t::floor); - if (portal != NULL) - { - GLSectorStackPortal *glportal = portal->GetGLPortal(); - glportal->AddSubsector(sub); - } + GLSectorStackPortal *glportal = portal->GetGLPortal(); + glportal->AddSubsector(sub); } } } diff --git a/src/gl/scene/gl_fakeflat.cpp b/src/gl/scene/gl_fakeflat.cpp index f3b452ca..6f97993d 100644 --- a/src/gl/scene/gl_fakeflat.cpp +++ b/src/gl/scene/gl_fakeflat.cpp @@ -44,6 +44,7 @@ #include "r_sky.h" #include "gl/renderer/gl_renderer.h" #include "gl/scene/gl_clipper.h" +#include "gl/data/gl_data.h" //========================================================================== @@ -70,10 +71,11 @@ bool gl_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto // Lines with stacked sectors must never block! - if (backsector->CeilingSkyBox && backsector->CeilingSkyBox->bAlways) return false; - if (backsector->FloorSkyBox && backsector->FloorSkyBox->bAlways) return false; - if (frontsector->CeilingSkyBox && frontsector->CeilingSkyBox->bAlways) return false; - if (frontsector->FloorSkyBox && frontsector->FloorSkyBox->bAlways) return false; + if (backsector->portals[sector_t::ceiling] != NULL || backsector->portals[sector_t::floor] != NULL || + frontsector->portals[sector_t::ceiling] != NULL || frontsector->portals[sector_t::floor] != NULL) + { + return false; + } // on large levels this distinction can save some time // That's a lot of avoided multiplications if there's a lot to see! diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index d8c6ccc1..78daecc2 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -602,14 +602,20 @@ void GLFlat::ProcessSector(sector_t * frontsector) if (frontsector->floorplane.ZatPoint(FIXED2FLOAT(viewx), FIXED2FLOAT(viewy)) <= FIXED2FLOAT(viewz)) { // process the original floor first. - if (frontsector->FloorSkyBox && frontsector->FloorSkyBox->bAlways) gl_drawinfo->AddFloorStack(sector); srf |= SSRF_RENDERFLOOR; lightlevel = GetFloorLight(frontsector); Colormap=frontsector->ColorMap; - stack = frontsector->FloorSkyBox && frontsector->FloorSkyBox->bAlways; - alpha= stack ? frontsector->GetAlpha(sector_t::floor)/65536.0f : 1.0f-frontsector->GetFloorReflect(); + if (frontsector->portals[sector_t::floor] != NULL) + { + gl_drawinfo->AddFloorStack(sector); + alpha = frontsector->GetAlpha(sector_t::floor)/65536.0f; + } + else + { + alpha = 1.0f-frontsector->GetFloorReflect(); + } if (frontsector->VBOHeightcheck(sector_t::floor)) { vboindex = frontsector->vboindex[sector_t::floor]; @@ -644,14 +650,21 @@ void GLFlat::ProcessSector(sector_t * frontsector) if (frontsector->ceilingplane.ZatPoint(FIXED2FLOAT(viewx), FIXED2FLOAT(viewy)) >= FIXED2FLOAT(viewz)) { // process the original ceiling first. - if (frontsector->CeilingSkyBox && frontsector->CeilingSkyBox->bAlways) gl_drawinfo->AddCeilingStack(sector); srf |= SSRF_RENDERCEILING; lightlevel = GetCeilingLight(frontsector); Colormap=frontsector->ColorMap; - stack = frontsector->CeilingSkyBox && frontsector->CeilingSkyBox->bAlways; - alpha=stack ? frontsector->GetAlpha(sector_t::ceiling)/65536.0f : 1.0f-frontsector->GetCeilingReflect(); + if (frontsector->portals[sector_t::ceiling] != NULL) + { + gl_drawinfo->AddCeilingStack(sector); + alpha = frontsector->GetAlpha(sector_t::ceiling)/65536.0f; + } + else + { + alpha = 1.0f-frontsector->GetCeilingReflect(); + } + if (frontsector->VBOHeightcheck(sector_t::ceiling)) { vboindex = frontsector->vboindex[sector_t::ceiling]; diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index 172fdca9..65f96467 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -680,7 +680,7 @@ void FDrawInfo::DrawUnhandledMissingTextures() if (seg->PartnerSeg && (seg->PartnerSeg->Subsector()->flags & SSECF_DEGENERATE)) continue; if (seg->backsector->transdoor) continue; if (seg->backsector->GetTexture(sector_t::ceiling)==skyflatnum) continue; - if (seg->backsector->CeilingSkyBox && seg->backsector->CeilingSkyBox->bAlways) continue; + if (seg->backsector->portals[sector_t::ceiling] != NULL) continue; if (!glset.notexturefill) FloodUpperGap(seg); } @@ -700,7 +700,7 @@ void FDrawInfo::DrawUnhandledMissingTextures() if (seg->frontsector->GetPlaneTexZ(sector_t::floor) > viewz) continue; // out of sight if (seg->backsector->transdoor) continue; if (seg->backsector->GetTexture(sector_t::floor)==skyflatnum) continue; - if (seg->backsector->FloorSkyBox && seg->backsector->FloorSkyBox->bAlways) continue; + if (seg->backsector->portals[sector_t::floor] != NULL) continue; if (!glset.notexturefill) FloodLowerGap(seg); } @@ -1059,7 +1059,7 @@ void FDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor) sub->validcount=validcount; // Has a sector stack or skybox itself! - if (sub->render_sector->CeilingSkyBox && sub->render_sector->CeilingSkyBox->bAlways) return; + if (sub->render_sector->portals[sector_t::ceiling] != NULL) return; // Don't bother processing unrendered subsectors if (sub->numlines>2 && !(ss_renderflags[DWORD(sub-subsectors)]&SSRF_PROCESSED)) return; @@ -1107,7 +1107,7 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor) sub->validcount=validcount; // Has a sector stack or skybox itself! - if (sub->render_sector->FloorSkyBox && sub->render_sector->FloorSkyBox->bAlways) return; + if (sub->render_sector->portals[sector_t::floor] != NULL) return; // Don't bother processing unrendered subsectors if (sub->numlines>2 && !(ss_renderflags[DWORD(sub-subsectors)]&SSRF_PROCESSED)) return; @@ -1156,7 +1156,8 @@ void FDrawInfo::ProcessSectorStacks() for (i=0;isubsectorcount;k++) + FPortal *portal = sec->portals[sector_t::ceiling]; + if (portal != NULL) for(int k=0;ksubsectorcount;k++) { subsector_t * sub = sec->subsectors[k]; if (ss_renderflags[sub-subsectors] & SSRF_PROCESSED) @@ -1176,19 +1177,14 @@ void FDrawInfo::ProcessSectorStacks() { subsector_t *sub = HandledSubsectors[j]; ss_renderflags[DWORD(sub-subsectors)] &= ~SSRF_RENDERCEILING; - FPortal *portal = gl_GetPortal(sec->CeilingSkyBox, sector_t::ceiling); - if (portal != NULL) + if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) { - if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) - { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal); - } - - GLSectorStackPortal *glportal = portal->GetGLPortal(); - glportal->AddSubsector(sub); + gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal); } + portal->GetGLPortal()->AddSubsector(sub); + if (sec->GetAlpha(sector_t::ceiling) != 0) { gl_subsectorrendernode * node = SSR_List.GetNew(); @@ -1204,7 +1200,8 @@ void FDrawInfo::ProcessSectorStacks() for (i=0;isubsectorcount;k++) + FPortal *portal = sec->portals[sector_t::floor]; + if (portal != NULL) for(int k=0;ksubsectorcount;k++) { subsector_t * sub = sec->subsectors[k]; if (ss_renderflags[sub-subsectors] & SSRF_PROCESSED) @@ -1226,18 +1223,14 @@ void FDrawInfo::ProcessSectorStacks() subsector_t *sub = HandledSubsectors[j]; ss_renderflags[DWORD(sub-subsectors)] &= ~SSRF_RENDERFLOOR; - FPortal *portal = gl_GetPortal(sec->FloorSkyBox, sector_t::floor); - if (portal != NULL) + if (sub->portalcoverage[sector_t::floor].subsectors == NULL) { - if (sub->portalcoverage[sector_t::floor].subsectors == NULL) - { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal); - } - - GLSectorStackPortal *glportal = portal->GetGLPortal(); - glportal->AddSubsector(sub); + gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal); } + GLSectorStackPortal *glportal = portal->GetGLPortal(); + glportal->AddSubsector(sub); + if (sec->GetAlpha(sector_t::floor)!=0) { gl_subsectorrendernode * node = SSR_List.GetNew(); diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 3fc77d52..88b86257 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -62,61 +62,27 @@ enum }; -//========================================================================== -// -// Calculate mirrorplane -// -//========================================================================== -void GLWall::MirrorPlane(secplane_t * plane, bool ceiling) -{ - if (!(gl.flags&RFL_NOSTENCIL)) - { - if (ceiling && FIXED2FLOAT(viewz) >= plane->ZatPoint(FIXED2FLOAT(viewx), FIXED2FLOAT(viewy))) return; - if (!ceiling && FIXED2FLOAT(viewz) <= plane->ZatPoint(FIXED2FLOAT(viewx), FIXED2FLOAT(viewy))) return; - type=RENDERWALL_PLANEMIRROR; - planemirror=plane; - PutWall(0); - } -} - //========================================================================== // // Calculate sky texture // //========================================================================== -void GLWall::SkyTexture(int sky1,ASkyViewpoint * skyboxx, bool ceiling) +void GLWall::SkyTexture(sector_t *sector, int plane) { GLSkyInfo skyinfo; + ASkyViewpoint * skyboxx = plane == sector_t::floor? sector->FloorSkyBox : sector->CeilingSkyBox; // JUSTHIT is used as an indicator that a skybox is in use. // This is to avoid recursion + if (!gl_noskyboxes && !(gl.flags&RFL_NOSTENCIL) && skyboxx && GLRenderer->mViewActor!=skyboxx && !(skyboxx->flags&MF_JUSTHIT)) { - if (!skyboxx->Mate) - { - type=RENDERWALL_SKYBOX; - skybox=skyboxx; - } - else - { - type=RENDERWALL_SECTORSTACK; - if (ceiling) - { - if (GLPortal::inlowerstack) return; - portal = gl_GetPortal(skyboxx, sector_t::ceiling); - } - else - { - if (GLPortal::inupperstack) return; - portal = gl_GetPortal(skyboxx, sector_t::floor); - } - if (portal == NULL) return; // invalid - } + type=RENDERWALL_SKYBOX; + skybox=skyboxx; } else { - if (skyboxx && skyboxx->Mate) return; - + int sky1 = sector->sky; memset(&skyinfo, 0, sizeof(skyinfo)); if ((sky1 & PL_SKYFLAT) && (sky1 & (PL_SKYFLAT-1)) && !(gl.flags&RFL_NOSTENCIL)) { @@ -147,7 +113,6 @@ void GLWall::SkyTexture(int sky1,ASkyViewpoint * skyboxx, bool ceiling) if (level.flags&LEVEL_DOUBLESKY) { skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, true); - if (!skyinfo.texture[1]) return; skyinfo.x_offset[1] = GLRenderer->mSky1Pos; skyinfo.doublesky = true; } @@ -166,8 +131,6 @@ void GLWall::SkyTexture(int sky1,ASkyViewpoint * skyboxx, bool ceiling) skyinfo.skytexno1=sky1texture; skyinfo.x_offset[0] = GLRenderer->mSky1Pos; } - if (!skyinfo.texture[0]) return; - } if (skyfog>0) { @@ -177,9 +140,8 @@ void GLWall::SkyTexture(int sky1,ASkyViewpoint * skyboxx, bool ceiling) else skyinfo.fadecolor=0; type=RENDERWALL_SKY; - sky = &skyinfo; + sky=UniqueSkies.Get(&skyinfo); } - PutWall(0); } @@ -188,34 +150,68 @@ void GLWall::SkyTexture(int sky1,ASkyViewpoint * skyboxx, bool ceiling) // Skies on one sided walls // //========================================================================== + void GLWall::SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2) { - bool ceilingsky = fs->GetTexture(sector_t::ceiling)==skyflatnum || (fs->CeilingSkyBox && fs->CeilingSkyBox->bAlways); - if (ceilingsky || fs->ceiling_reflect) - { - ztop[0]=ztop[1]=32768.0f; - zbottom[0]=zceil[0]; - zbottom[1]=zceil[1]; - if (ceilingsky) SkyTexture(fs->sky,fs->CeilingSkyBox, true); - else MirrorPlane(&fs->ceilingplane, true); - } - bool floorsky = fs->GetTexture(sector_t::floor)==skyflatnum || (fs->FloorSkyBox && fs->FloorSkyBox->bAlways); - if (floorsky || fs->floor_reflect) - { - ztop[0]=zfloor[0]; - ztop[1]=zfloor[1]; - zbottom[0]=zbottom[1]=-32768.0f; - if (floorsky) SkyTexture(fs->sky,fs->FloorSkyBox, false); - else MirrorPlane(&fs->floorplane, false); - } -} + FPortal *portal; + portal = fs->portals[sector_t::ceiling]; + if (portal != NULL) + { + type=RENDERWALL_SECTORSTACK; + if (GLPortal::inlowerstack) goto floor; + this->portal = portal; + } + else if (fs->GetTexture(sector_t::ceiling)==skyflatnum) + { + SkyTexture(fs, sector_t::ceiling); + } + else if (fs->GetCeilingReflect() > 0) + { + // This must be done in floats to avoid overflows + if (FIXED2DBL(viewz) >= fs->ceilingplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) goto floor; + type=RENDERWALL_PLANEMIRROR; + planemirror = &fs->ceilingplane; + } + else goto floor; + + ztop[0]=ztop[1]=32768.0f; + zbottom[0]=zceil[0]; + zbottom[1]=zceil[1]; + PutWall(0); + +floor: + portal = fs->portals[sector_t::floor]; + if (portal != NULL) + { + type=RENDERWALL_SECTORSTACK; + if (GLPortal::inupperstack) return; + this->portal = portal; + } + else if (fs->GetTexture(sector_t::floor)==skyflatnum) + { + SkyTexture(fs, sector_t::floor); + } + else if (fs->GetFloorReflect() > 0) + { + if (FIXED2DBL(viewz) <= fs->floorplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) return; + type=RENDERWALL_PLANEMIRROR; + planemirror = &fs->floorplane; + } + else return; + + ztop[0]=zfloor[0]; + ztop[1]=zfloor[1]; + zbottom[0]=zbottom[1]=-32768.0f; + PutWall(0); +} //========================================================================== // // Upper Skies on two sided walls // //========================================================================== + void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2) { if (fs->GetTexture(sector_t::ceiling)==skyflatnum) @@ -246,7 +242,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex ztop[0]=ztop[1]=32768.0f; zbottom[0]=zbottom[1]= FIXED2FLOAT(bs->ceilingplane.ZatPoint(v2) + seg->sidedef->GetTextureYOffset(side_t::mid)); - SkyTexture(fs->sky,fs->CeilingSkyBox, true); + SkyTexture(fs, sector_t::ceiling); return; } } @@ -268,25 +264,40 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex zbottom[1]=FIXED2FLOAT(bs->ceilingplane.ZatPoint(v2)); flags|=GLWF_SKYHACK; // mid textures on such lines need special treatment! } - - SkyTexture(fs->sky,fs->CeilingSkyBox, true); } else { - bool ceilingsky = (fs->CeilingSkyBox && fs->CeilingSkyBox->bAlways && fs->CeilingSkyBox!=bs->CeilingSkyBox); - if (ceilingsky || fs->ceiling_reflect) - { - // stacked sectors - fixed_t fsc1=fs->ceilingplane.ZatPoint(v1); - fixed_t fsc2=fs->ceilingplane.ZatPoint(v2); + FPortal *pfront = fs->portals[sector_t::ceiling]; + FPortal *pback = bs->portals[sector_t::ceiling]; + if (pfront == NULL && (fs->GetCeilingReflect() == 0 || pfront == pback)) return; - ztop[0]=ztop[1]=32768.0f; - zbottom[0]=FIXED2FLOAT(fsc1); - zbottom[1]=FIXED2FLOAT(fsc2); - if (ceilingsky) SkyTexture(fs->sky,fs->CeilingSkyBox, true); - else MirrorPlane(&fs->ceilingplane, true); - } + // stacked sectors + fixed_t fsc1=fs->ceilingplane.ZatPoint(v1); + fixed_t fsc2=fs->ceilingplane.ZatPoint(v2); + + ztop[0]=ztop[1]=32768.0f; + zbottom[0]=FIXED2FLOAT(fsc1); + zbottom[1]=FIXED2FLOAT(fsc2); } + + FPortal *portal = fs->portals[sector_t::ceiling]; + if (portal != NULL) + { + type=RENDERWALL_SECTORSTACK; + if (GLPortal::inlowerstack) return; + this->portal = portal; + } + else if (fs->GetTexture(sector_t::ceiling)==skyflatnum) + { + SkyTexture(fs, sector_t::ceiling); + } + else // if (fs->ceiling_reflect != 0) + { + if (FIXED2DBL(viewz) >= fs->ceilingplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) return; + type=RENDERWALL_PLANEMIRROR; + planemirror = &fs->ceilingplane; + } + PutWall(0); } @@ -295,6 +306,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex // Lower Skies on two sided walls // //========================================================================== + void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2) { if (fs->GetTexture(sector_t::floor)==skyflatnum) @@ -333,23 +345,39 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver flags|=GLWF_SKYHACK; // mid textures on such lines need special treatment! } - SkyTexture(fs->sky,fs->FloorSkyBox, false); + SkyTexture(fs, sector_t::floor); } else { - bool floorsky = (fs->FloorSkyBox && fs->FloorSkyBox->bAlways && fs->FloorSkyBox!=bs->FloorSkyBox); - if (floorsky || fs->floor_reflect) - { - // stacked sectors - fixed_t fsc1=fs->floorplane.ZatPoint(v1); - fixed_t fsc2=fs->floorplane.ZatPoint(v2); + FPortal *pfront = fs->portals[sector_t::floor]; + FPortal *pback = bs->portals[sector_t::floor]; + if (pfront == NULL && (fs->GetFloorReflect() == 0 || pfront == pback)) return; - zbottom[0]=zbottom[1]=-32768.0f; - ztop[0]=FIXED2FLOAT(fsc1); - ztop[1]=FIXED2FLOAT(fsc2); + // stacked sectors + fixed_t fsc1=fs->floorplane.ZatPoint(v1); + fixed_t fsc2=fs->floorplane.ZatPoint(v2); - if (floorsky) SkyTexture(fs->sky,fs->FloorSkyBox, false); - else MirrorPlane(&fs->floorplane, false); - } + zbottom[0]=zbottom[1]=-32768.0f; + ztop[0]=FIXED2FLOAT(fsc1); + ztop[1]=FIXED2FLOAT(fsc2); } + + FPortal *portal = fs->portals[sector_t::floor]; + if (portal != NULL) + { + type=RENDERWALL_SECTORSTACK; + if (GLPortal::inupperstack) return; + this->portal = portal; + } + else if (fs->GetTexture(sector_t::floor)==skyflatnum) + { + SkyTexture(fs, sector_t::floor); + } + else // if (fs->floor_reflect != 0) + { + if (FIXED2DBL(viewz) <= fs->floorplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) return; + type=RENDERWALL_PLANEMIRROR; + planemirror = &fs->floorplane; + } + PutWall(0); } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index d33b9900..80362e21 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -164,7 +164,7 @@ private: void FloodPlane(int pass); void MirrorPlane(secplane_t * plane, bool ceiling); - void SkyTexture(int sky1,ASkyViewpoint * skyboxx, bool ceiling); + void SkyTexture(sector_t *sector, int plane); void SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2); void SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2); diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 42f63340..47f1bb1c 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -244,7 +244,6 @@ void GLWall::PutWall(bool translucent) case RENDERWALL_SKY: //@sync-portal - sky=UniqueSkies.Get(sky); portal=GLPortal::FindPortal(sky); if (!portal) portal=new GLSkyPortal(sky); portal->AddLine(this); @@ -503,7 +502,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) if (fs->GetTexture(sector_t::ceiling) == skyflatnum) { - SkyTexture(fs->sky, fs->CeilingSkyBox, true); + SkyTexture(fs, sector_t::floor); } else { @@ -522,8 +521,8 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) if (gl_fixedcolormap) hi.colormap.GetFixedColormap(); horizon = &hi; - PutWall(0); } + PutWall(0); ztop[1] = ztop[0] = zbottom[0]; } @@ -532,7 +531,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) zbottom[1] = zbottom[0] = FIXED2FLOAT(fs->GetPlaneTexZ(sector_t::floor)); if (fs->GetTexture(sector_t::floor) == skyflatnum) { - SkyTexture(fs->sky, fs->FloorSkyBox, false); + SkyTexture(fs, sector_t::floor); } else { @@ -551,8 +550,8 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) if (gl_fixedcolormap) hi.colormap.GetFixedColormap(); horizon=&hi; - PutWall(0); } + PutWall(0); } return true; } diff --git a/src/r_defs.h b/src/r_defs.h index 48b14718..0e852c2a 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -319,6 +319,7 @@ struct subsector_t; struct sector_t; struct side_t; extern bool gl_plane_reflection_i; +struct FPortal; // Ceiling/floor flags enum @@ -751,6 +752,7 @@ struct sector_t fixed_t transdoorheight; // for transparent door hacks int subsectorcount; // list of subsectors subsector_t ** subsectors; + FPortal * portals[2]; // floor and ceiling portals enum { From 4e7ed99c6bb4860090be7c280c2d60901801c42d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 13 Nov 2010 14:15:52 +0000 Subject: [PATCH 34/82] - removed all checks for stencil support except for the places where actual rendering takes place. Compatibility mode was broken anyway so there's really not much of a point checking for it anymore. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1093 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_flats.cpp | 5 ----- src/gl/scene/gl_portal.cpp | 9 +++++++++ src/gl/scene/gl_sky.cpp | 6 +++--- src/gl/scene/gl_walls.cpp | 5 ++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 78daecc2..3cd6f377 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -449,11 +449,6 @@ inline void GLFlat::PutFlat(bool fog) { Colormap.GetFixedColormap(); } - if ((gl.flags&RFL_NOSTENCIL) && !(renderflags&SSRF_RENDER3DPLANES)) - { - renderstyle=STYLE_Translucent; - alpha=1.f; - } if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog) { int list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 01ec552b..c220e839 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -466,6 +466,15 @@ void GLPortal::EndFrame() { GLPortal * p; + if (!(gl.flags & RFL_NOSTENCIL)) + { + while (portals.Pop(p) && p) + { + delete p; + } + return; + } + if (gl_portalinfo) { Printf("%s%d portals, depth = %d\n%s{\n", indent.GetChars(), portals.Size(), renderdepth, indent.GetChars()); diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 88b86257..12c6f755 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -75,7 +75,7 @@ void GLWall::SkyTexture(sector_t *sector, int plane) // JUSTHIT is used as an indicator that a skybox is in use. // This is to avoid recursion - if (!gl_noskyboxes && !(gl.flags&RFL_NOSTENCIL) && skyboxx && GLRenderer->mViewActor!=skyboxx && !(skyboxx->flags&MF_JUSTHIT)) + if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor!=skyboxx && !(skyboxx->flags&MF_JUSTHIT)) { type=RENDERWALL_SKYBOX; skybox=skyboxx; @@ -84,7 +84,7 @@ void GLWall::SkyTexture(sector_t *sector, int plane) { int sky1 = sector->sky; memset(&skyinfo, 0, sizeof(skyinfo)); - if ((sky1 & PL_SKYFLAT) && (sky1 & (PL_SKYFLAT-1)) && !(gl.flags&RFL_NOSTENCIL)) + if ((sky1 & PL_SKYFLAT) && (sky1 & (PL_SKYFLAT-1))) { const line_t *l = &lines[(sky1&(PL_SKYFLAT-1))-1]; const side_t *s = l->sidedef[0]; @@ -117,7 +117,7 @@ void GLWall::SkyTexture(sector_t *sector, int plane) skyinfo.doublesky = true; } - if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT && !(gl.flags&RFL_NOSTENCIL)) || (level.flags&LEVEL_DOUBLESKY)) && + if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) && sky2texture!=sky1texture) // If both skies are equal use the scroll offset of the first! { skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, true); diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 47f1bb1c..032faa2d 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -752,8 +752,7 @@ void GLWall::DoTexture(int _type,seg_t * seg, int peg, gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(texpos), seg->sidedef->GetTextureYScale(texpos)); - type = (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && - !(gl.flags & RFL_NOSTENCIL) && gl_mirrors) ? RENDERWALL_MIRROR : _type; + type = (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && gl_mirrors) ? RENDERWALL_MIRROR : _type; float floatceilingref = FIXED2FLOAT(ceilingrefheight) + FIXED2FLOAT(tci.RowOffset(seg->sidedef->GetTextureYOffset(texpos))) + @@ -1551,7 +1550,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) } - if (seg->linedef->special==Line_Horizon && !(gl.flags&RFL_NOSTENCIL)) + if (seg->linedef->special==Line_Horizon) { SkyNormal(frontsector,v1,v2); DoHorizon(seg,frontsector, v1,v2); From dbaf9807cf91d44dedf0a545e2c85cc21b83004f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Nov 2010 09:49:44 +0000 Subject: [PATCH 35/82] - Code cleanup. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/branches/portalcoverage@1094 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_portal.cpp | 78 +++++++++++++++++++++++++----------- src/gl/scene/gl_portal.h | 1 + src/gl/system/gl_interface.h | 21 +++++----- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index c220e839..d6803308 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -290,6 +290,9 @@ bool GLPortal::Start(bool usestencil, bool doquery) savedviewactor=GLRenderer->mViewActor; savedviewangle=viewangle; savedviewarea=in_area; + + NextPortal = GLRenderer->mCurrentPortal; + GLRenderer->mCurrentPortal = NULL; // Portals which need this have to set it themselves PortalAll.Unclock(); return true; } @@ -337,6 +340,7 @@ void GLPortal::End(bool usestencil) bool needdepth = NeedDepthBuffer(); PortalAll.Clock(); + GLRenderer->mCurrentPortal = NextPortal; if (clipsave) gl.Enable (GL_CLIP_PLANE0+renderdepth-1); if (usestencil) { @@ -635,6 +639,38 @@ void GLSkyboxPortal::DrawContents() extralight = saved_extralight; } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// +// +// Sector stack Portal +// +// +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// GLSectorStackPortal::SetupCoverage +// +//----------------------------------------------------------------------------- + +void GLSectorStackPortal::SetupCoverage() +{ + memset(¤tmapsection[0], 0, currentmapsection.Size()); + for(unsigned i=0; iplane; + for(int j=0;jportalcoverage[plane].sscount; j++) + { + subsector_t *dsub = &::subsectors[sub->portalcoverage[plane].subsectors[j]]; + currentmapsection[dsub->mapsection>>3] |= 1 << (dsub->mapsection&7); + gl_drawinfo->ss_renderflags[dsub-::subsectors] |= SSRF_SEEN; + } + } +} + //----------------------------------------------------------------------------- // // GLSectorStackPortal::DrawContents @@ -655,7 +691,7 @@ void GLSectorStackPortal::DrawContents() // avoid recursions! if (origin->plane == sector_t::ceiling) inupperstack=true; - else inlowerstack=true; + else if (origin->plane == sector_t::floor) inlowerstack=true; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SetupCoverage(); @@ -755,28 +791,6 @@ int GLSectorStackPortal::ClipSeg(seg_t *seg) #endif } -//----------------------------------------------------------------------------- -// -// GLSectorStackPortal::SetupCoverage -// -//----------------------------------------------------------------------------- - -void GLSectorStackPortal::SetupCoverage() -{ - memset(¤tmapsection[0], 0, currentmapsection.Size()); - for(unsigned i=0; iplane; - for(int j=0;jportalcoverage[plane].sscount; j++) - { - subsector_t *dsub = &::subsectors[sub->portalcoverage[plane].subsectors[j]]; - currentmapsection[dsub->mapsection>>3] |= 1 << (dsub->mapsection&7); - gl_drawinfo->ss_renderflags[dsub-::subsectors] |= SSRF_SEEN; - } - } -} - //----------------------------------------------------------------------------- // @@ -818,11 +832,22 @@ int GLSectorStackPortal::ClipPoint(fixed_t x, fixed_t y) return PClip_Inside; } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// +// +// Plane Mirror Portal +// +// +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // // GLPlaneMirrorPortal::DrawContents // //----------------------------------------------------------------------------- + void GLPlaneMirrorPortal::DrawContents() { if (renderdepth>r_mirror_recursions) @@ -856,6 +881,13 @@ void GLPlaneMirrorPortal::DrawContents() PlaneMirrorMode=old_pm; } +//----------------------------------------------------------------------------- +// +// GLPlaneMirrorPortal::DrawContents +// +//----------------------------------------------------------------------------- + + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index f255ad8e..6b43cea4 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -102,6 +102,7 @@ private: AActor * savedviewactor; area_t savedviewarea; unsigned char clipsave; + GLPortal *NextPortal; protected: TArray lines; diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 0c5b6c2a..c2c39f95 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -5,20 +5,17 @@ enum RenderFlags { RFL_NPOT_TEXTURE=1, RFL_NOSTENCIL=2, - RFL_FRAGMENT_PROGRAM=4, - RFL_OCCLUSION_QUERY=16, - RFL_TEX_ENV_COMBINE4_NV=32, - RFL_TEX_ENV_COMBINE3_ATI=64, + RFL_OCCLUSION_QUERY=4, // [BB] Added texture compression flags. - RFL_TEXTURE_COMPRESSION=128, - RFL_TEXTURE_COMPRESSION_S3TC=256, + RFL_TEXTURE_COMPRESSION=8, + RFL_TEXTURE_COMPRESSION_S3TC=16, - RFL_VBO = 512, - RFL_MAP_BUFFER_RANGE = 1024, - RFL_FRAMEBUFFER = 2048, - RFL_TEXTUREBUFFER = 4096, - RFL_NVIDIA = 8192, - RFL_ATI = 16384, + RFL_VBO = 32, + RFL_MAP_BUFFER_RANGE = 64, + RFL_FRAMEBUFFER = 128, + RFL_TEXTUREBUFFER = 256, + RFL_NVIDIA = 512, + RFL_ATI = 1024, RFL_GL_20 = 0x10000000, From e9d8365156a8b88360b801c56a6d876c0461f0a2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Nov 2010 12:37:59 +0000 Subject: [PATCH 36/82] - fixed: Portal flags must be recursive counters instead of booleans. - fixed: Stencil check in portal code was negated. - version bump git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1097 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_portal.cpp | 16 ++++++++++------ src/gl/scene/gl_portal.h | 4 ++-- src/version.h | 6 +++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index d6803308..a8092aef 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -83,8 +83,8 @@ int GLPortal::renderdepth; int GLPortal::PlaneMirrorMode; GLuint GLPortal::QueryObject; -bool GLPortal::inupperstack; -bool GLPortal::inlowerstack; +int GLPortal::inupperstack; +int GLPortal::inlowerstack; bool GLPortal::inskybox; UniqueList UniqueSkies; @@ -439,7 +439,8 @@ void GLPortal::StartFrame() portals.Push(p); if (renderdepth==0) { - inskybox=inupperstack=inlowerstack=false; + inskybox=false; + inupperstack=inlowerstack=0; } renderdepth++; } @@ -470,7 +471,7 @@ void GLPortal::EndFrame() { GLPortal * p; - if (!(gl.flags & RFL_NOSTENCIL)) + if (gl.flags & RFL_NOSTENCIL) { while (portals.Pop(p) && p) { @@ -690,13 +691,16 @@ void GLSectorStackPortal::DrawContents() validcount++; // avoid recursions! - if (origin->plane == sector_t::ceiling) inupperstack=true; - else if (origin->plane == sector_t::floor) inlowerstack=true; + if (origin->plane == sector_t::ceiling) inupperstack++; + else if (origin->plane == sector_t::floor) inlowerstack++; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SetupCoverage(); ClearClipper(); GLRenderer->DrawScene(); + + if (origin->plane == sector_t::ceiling) inupperstack--; + else if (origin->plane == sector_t::floor) inlowerstack--; } //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 6b43cea4..faa136f1 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -88,8 +88,8 @@ protected: public: static int PlaneMirrorMode; - static bool inupperstack; - static bool inlowerstack; + static int inupperstack; + static int inlowerstack; static bool inskybox; private: diff --git a/src/version.h b/src/version.h index bb3cd5f4..29a30477 100644 --- a/src/version.h +++ b/src/version.h @@ -41,15 +41,15 @@ /** Lots of different version numbers **/ -#define DOTVERSIONSTR_NOREV "1.5.3" +#define DOTVERSIONSTR_NOREV "1.5.4" #define ZDVER_STRING "2.5.0" // The version string the user actually sees. #define DOTVERSIONSTR DOTVERSIONSTR_NOREV " (r" SVN_REVISION_STRING ") / ZDoom " ZDVER_STRING " (r" ZD_SVN_REVISION_STRING ")" // The version as seen in the Windows resource -#define RC_FILEVERSION 1,5,3,SVN_REVISION_NUMBER -#define RC_PRODUCTVERSION 1,5,3,0 +#define RC_FILEVERSION 1,5,4,SVN_REVISION_NUMBER +#define RC_PRODUCTVERSION 1,5,4,0 #define RC_FILEVERSION2 DOTVERSIONSTR #define RC_PRODUCTVERSION2 "1.5" From 5273df99b91e0f47df383ffd81dc826aad2b132b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Nov 2010 17:51:14 +0000 Subject: [PATCH 37/82] - Sigh. Why is it that every glitch the renderer can produce gets abzsed somehow? Had to add a few more checks for portal planes because ZPack's E1M0 pretty much abused every single conceivable glitch in the portal logic. - fixed: When rendering a portal each node that contains a 'seen' subsector must also be considered 'seen'. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1100 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_bsp.cpp | 3 ++- src/gl/scene/gl_drawinfo.cpp | 2 ++ src/gl/scene/gl_drawinfo.h | 1 + src/gl/scene/gl_portal.cpp | 25 +++++++++++++++++++++++-- src/gl/scene/gl_sky.cpp | 6 ++++-- src/gl/scene/gl_walls.cpp | 25 +++++++++++++++++++++++-- 6 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 4198b9c7..4bf311b8 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -551,7 +551,8 @@ void gl_RenderBSPNode (void *node) // It is not necessary to use the slower precise version here if (!clipper.CheckBox(bsp->bbox[side])) { - return; + //if (!(gl_drawinfo->no_renderflags[bsp-nodes] & SSRF_SEEN)) + return; } node = bsp->children[side]; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 1e52399d..972dd168 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -940,9 +940,11 @@ void FDrawInfo::StartScene() sectorrenderflags.Resize(numsectors); ss_renderflags.Resize(numsubsectors); + no_renderflags.Resize(numsubsectors); memset(§orrenderflags[0], 0, numsectors*sizeof(sectorrenderflags[0])); memset(&ss_renderflags[0], 0, numsubsectors*sizeof(ss_renderflags[0])); + memset(&no_renderflags[0], 0, numnodes*sizeof(no_renderflags[0])); next=gl_drawinfo; gl_drawinfo=this; diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index f669b3aa..c598d988 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -191,6 +191,7 @@ struct FDrawInfo TArray sectorrenderflags; TArray ss_renderflags; + TArray no_renderflags; TArray MissingUpperTextures; TArray MissingLowerTextures; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index a8092aef..bfd82557 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -656,6 +656,26 @@ void GLSkyboxPortal::DrawContents() // //----------------------------------------------------------------------------- +static BYTE SetCoverage(void *node) +{ + if (numnodes == 0) + { + return 0; + } + if (!((size_t)node & 1)) // Keep going until found a subsector + { + node_t *bsp = (node_t *)node; + BYTE coverage = SetCoverage(bsp->children[0]) | SetCoverage(bsp->children[1]); + gl_drawinfo->no_renderflags[bsp-nodes] = coverage; + return coverage; + } + else + { + subsector_t *sub = (subsector_t *)((BYTE *)node - 1); + return gl_drawinfo->ss_renderflags[sub-subsectors] & SSRF_SEEN; + } +} + void GLSectorStackPortal::SetupCoverage() { memset(¤tmapsection[0], 0, currentmapsection.Size()); @@ -670,6 +690,7 @@ void GLSectorStackPortal::SetupCoverage() gl_drawinfo->ss_renderflags[dsub-::subsectors] |= SSRF_SEEN; } } + SetCoverage(&nodes[numnodes-1]); } //----------------------------------------------------------------------------- @@ -692,7 +713,7 @@ void GLSectorStackPortal::DrawContents() // avoid recursions! if (origin->plane == sector_t::ceiling) inupperstack++; - else if (origin->plane == sector_t::floor) inlowerstack++; + else /*if (origin->plane == sector_t::floor)*/ inlowerstack++; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SetupCoverage(); @@ -700,7 +721,7 @@ void GLSectorStackPortal::DrawContents() GLRenderer->DrawScene(); if (origin->plane == sector_t::ceiling) inupperstack--; - else if (origin->plane == sector_t::floor) inlowerstack--; + else /*if (origin->plane == sector_t::floor)*/ inlowerstack--; } //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 12c6f755..126273a8 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -79,6 +79,10 @@ void GLWall::SkyTexture(sector_t *sector, int plane) { type=RENDERWALL_SKYBOX; skybox=skyboxx; + if (skybox->x == -129*FRACUNIT) + { + __asm nop + } } else { @@ -344,8 +348,6 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver ztop[1]=FIXED2FLOAT(bs->floorplane.ZatPoint(v2)); flags|=GLWF_SKYHACK; // mid textures on such lines need special treatment! } - - SkyTexture(fs, sector_t::floor); } else { diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index b6894d66..0422fb2b 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -502,7 +502,17 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) if (fs->GetTexture(sector_t::ceiling) == skyflatnum) { - SkyTexture(fs, sector_t::floor); + portal = fs->portals[sector_t::ceiling]; + if (portal != NULL) + { + type=RENDERWALL_SECTORSTACK; + if (GLPortal::inlowerstack) goto floor; + this->portal = portal; + } + else + { + SkyTexture(fs, sector_t::ceiling); + } } else { @@ -526,12 +536,23 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) ztop[1] = ztop[0] = zbottom[0]; } +floor: if (viewz > fs->GetPlaneTexZ(sector_t::floor)) { zbottom[1] = zbottom[0] = FIXED2FLOAT(fs->GetPlaneTexZ(sector_t::floor)); if (fs->GetTexture(sector_t::floor) == skyflatnum) { - SkyTexture(fs, sector_t::floor); + portal = fs->portals[sector_t::floor]; + if (portal != NULL) + { + type=RENDERWALL_SECTORSTACK; + if (GLPortal::inupperstack) return true; + this->portal = portal; + } + else + { + SkyTexture(fs, sector_t::floor); + } } else { From 1334c9acf81385102cf21742ce41b7bdf855293e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Nov 2010 20:41:16 +0000 Subject: [PATCH 38/82] - fixed: reflective floors did not work anymore. - eliminated some redundant code. - renamed a few variables in sector so that they can be indexed with the plane ID. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1101 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.cpp | 4 +- src/gl/scene/gl_flats.cpp | 4 +- src/gl/scene/gl_portal.cpp | 11 +- src/gl/scene/gl_portal.h | 2 +- src/gl/scene/gl_sky.cpp | 239 ++++++++++++++----------------------- src/gl/scene/gl_wall.h | 5 +- src/gl/scene/gl_walls.cpp | 29 +---- src/p_saveg.cpp | 2 +- src/r_defs.h | 5 +- src/version.h | 6 +- 10 files changed, 113 insertions(+), 194 deletions(-) diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index 6592838f..4481915d 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -153,8 +153,8 @@ static int LS_Sector_SetPlaneReflection (line_t *ln, AActor *it, bool backSide, while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) { sector_t * s = §ors[secnum]; - if (s->floorplane.a==0 && s->floorplane.b==0) s->floor_reflect = arg1/255.f; - if (s->ceilingplane.a==0 && s->ceilingplane.b==0) sectors[secnum].ceiling_reflect = arg2/255.f; + if (s->floorplane.a==0 && s->floorplane.b==0) s->reflect[sector_t::floor] = arg1/255.f; + if (s->ceilingplane.a==0 && s->ceilingplane.b==0) sectors[secnum].reflect[sector_t::ceiling] = arg2/255.f; } return true; diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 3cd6f377..876ef5aa 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -609,7 +609,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) } else { - alpha = 1.0f-frontsector->GetFloorReflect(); + alpha = 1.0f-frontsector->GetReflect(sector_t::floor); } if (frontsector->VBOHeightcheck(sector_t::floor)) { @@ -657,7 +657,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) } else { - alpha = 1.0f-frontsector->GetCeilingReflect(); + alpha = 1.0f-frontsector->GetReflect(sector_t::ceiling); } if (frontsector->VBOHeightcheck(sector_t::ceiling)) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index bfd82557..8b2513df 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -83,8 +83,7 @@ int GLPortal::renderdepth; int GLPortal::PlaneMirrorMode; GLuint GLPortal::QueryObject; -int GLPortal::inupperstack; -int GLPortal::inlowerstack; +int GLPortal::instack[2]; bool GLPortal::inskybox; UniqueList UniqueSkies; @@ -440,7 +439,7 @@ void GLPortal::StartFrame() if (renderdepth==0) { inskybox=false; - inupperstack=inlowerstack=0; + instack[sector_t::floor]=instack[sector_t::ceiling]=0; } renderdepth++; } @@ -712,16 +711,14 @@ void GLSectorStackPortal::DrawContents() validcount++; // avoid recursions! - if (origin->plane == sector_t::ceiling) inupperstack++; - else /*if (origin->plane == sector_t::floor)*/ inlowerstack++; + if (origin->plane != -1) instack[origin->plane]++; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SetupCoverage(); ClearClipper(); GLRenderer->DrawScene(); - if (origin->plane == sector_t::ceiling) inupperstack--; - else /*if (origin->plane == sector_t::floor)*/ inlowerstack--; + if (origin->plane != -1) instack[origin->plane]--; } //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index faa136f1..8746173a 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -89,7 +89,7 @@ protected: public: static int PlaneMirrorMode; static int inupperstack; - static int inlowerstack; + static int instack[2]; static bool inskybox; private: diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 126273a8..ec40954e 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -67,85 +67,100 @@ enum // Calculate sky texture // //========================================================================== -void GLWall::SkyTexture(sector_t *sector, int plane) +void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) { - GLSkyInfo skyinfo; - ASkyViewpoint * skyboxx = plane == sector_t::floor? sector->FloorSkyBox : sector->CeilingSkyBox; - - // JUSTHIT is used as an indicator that a skybox is in use. - // This is to avoid recursion - - if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor!=skyboxx && !(skyboxx->flags&MF_JUSTHIT)) + FPortal *portal = sector->portals[plane]; + if (portal != NULL) { - type=RENDERWALL_SKYBOX; - skybox=skyboxx; - if (skybox->x == -129*FRACUNIT) - { - __asm nop - } + type=RENDERWALL_SECTORSTACK; + if (GLPortal::instack[1-plane]) return; + this->portal = portal; } - else + else if (sector->GetTexture(plane)==skyflatnum) { - int sky1 = sector->sky; - memset(&skyinfo, 0, sizeof(skyinfo)); - if ((sky1 & PL_SKYFLAT) && (sky1 & (PL_SKYFLAT-1))) - { - const line_t *l = &lines[(sky1&(PL_SKYFLAT-1))-1]; - const side_t *s = l->sidedef[0]; - int pos; - - if (level.flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid()) - { - pos = side_t::bottom; - } - else - { - pos = side_t::top; - } + GLSkyInfo skyinfo; + ASkyViewpoint * skyboxx = plane == sector_t::floor? sector->FloorSkyBox : sector->CeilingSkyBox; - FTextureID texno = s->GetTexture(pos); - skyinfo.texture[0] = FMaterial::ValidateTexture(texno, true); - if (!skyinfo.texture[0] || skyinfo.texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky; - skyinfo.skytexno1 = texno; - skyinfo.x_offset[0] = ANGLE_TO_FLOAT(s->GetTextureXOffset(pos)); - skyinfo.y_offset = FIXED2FLOAT(s->GetTextureYOffset(pos)); - skyinfo.mirrored = !l->args[2]; + // JUSTHIT is used as an indicator that a skybox is in use. + // This is to avoid recursion + + if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor!=skyboxx && !(skyboxx->flags&MF_JUSTHIT)) + { + type=RENDERWALL_SKYBOX; + skybox=skyboxx; } else { - normalsky: - if (level.flags&LEVEL_DOUBLESKY) + int sky1 = sector->sky; + memset(&skyinfo, 0, sizeof(skyinfo)); + if ((sky1 & PL_SKYFLAT) && (sky1 & (PL_SKYFLAT-1))) { - skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, true); - skyinfo.x_offset[1] = GLRenderer->mSky1Pos; - skyinfo.doublesky = true; - } - - if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) && - sky2texture!=sky1texture) // If both skies are equal use the scroll offset of the first! - { - skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, true); - skyinfo.skytexno1=sky2texture; - skyinfo.sky2 = true; - skyinfo.x_offset[0] = GLRenderer->mSky2Pos; + const line_t *l = &lines[(sky1&(PL_SKYFLAT-1))-1]; + const side_t *s = l->sidedef[0]; + int pos; + + if (level.flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid()) + { + pos = side_t::bottom; + } + else + { + pos = side_t::top; + } + + FTextureID texno = s->GetTexture(pos); + skyinfo.texture[0] = FMaterial::ValidateTexture(texno, true); + if (!skyinfo.texture[0] || skyinfo.texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky; + skyinfo.skytexno1 = texno; + skyinfo.x_offset[0] = ANGLE_TO_FLOAT(s->GetTextureXOffset(pos)); + skyinfo.y_offset = FIXED2FLOAT(s->GetTextureYOffset(pos)); + skyinfo.mirrored = !l->args[2]; } else { - skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, true); - skyinfo.skytexno1=sky1texture; - skyinfo.x_offset[0] = GLRenderer->mSky1Pos; + normalsky: + if (level.flags&LEVEL_DOUBLESKY) + { + skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, true); + skyinfo.x_offset[1] = GLRenderer->mSky1Pos; + skyinfo.doublesky = true; + } + + if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) && + sky2texture!=sky1texture) // If both skies are equal use the scroll offset of the first! + { + skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, true); + skyinfo.skytexno1=sky2texture; + skyinfo.sky2 = true; + skyinfo.x_offset[0] = GLRenderer->mSky2Pos; + } + else + { + skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, true); + skyinfo.skytexno1=sky1texture; + skyinfo.x_offset[0] = GLRenderer->mSky1Pos; + } } - } - if (skyfog>0) - { - skyinfo.fadecolor=Colormap.FadeColor; - skyinfo.fadecolor.a=0; - } - else skyinfo.fadecolor=0; + if (skyfog>0) + { + skyinfo.fadecolor=Colormap.FadeColor; + skyinfo.fadecolor.a=0; + } + else skyinfo.fadecolor=0; - type=RENDERWALL_SKY; - sky=UniqueSkies.Get(&skyinfo); + type=RENDERWALL_SKY; + sky=UniqueSkies.Get(&skyinfo); + } } + else if (allowreflect && sector->GetReflect(plane) > 0) + { + if ((plane == sector_t::ceiling && viewz > sector->ceilingplane.d) || + (plane == sector_t::floor && viewz < -sector->floorplane.d)) return; + type=RENDERWALL_PLANEMIRROR; + planemirror = plane == sector_t::ceiling? §or->ceilingplane : §or->floorplane; + } + else return; + PutWall(0); } @@ -157,57 +172,15 @@ void GLWall::SkyTexture(sector_t *sector, int plane) void GLWall::SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2) { - FPortal *portal; - - portal = fs->portals[sector_t::ceiling]; - if (portal != NULL) - { - type=RENDERWALL_SECTORSTACK; - if (GLPortal::inlowerstack) goto floor; - this->portal = portal; - } - else if (fs->GetTexture(sector_t::ceiling)==skyflatnum) - { - SkyTexture(fs, sector_t::ceiling); - } - else if (fs->GetCeilingReflect() > 0) - { - // This must be done in floats to avoid overflows - if (FIXED2DBL(viewz) >= fs->ceilingplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) goto floor; - type=RENDERWALL_PLANEMIRROR; - planemirror = &fs->ceilingplane; - } - else goto floor; - ztop[0]=ztop[1]=32768.0f; zbottom[0]=zceil[0]; zbottom[1]=zceil[1]; - PutWall(0); - -floor: - portal = fs->portals[sector_t::floor]; - if (portal != NULL) - { - type=RENDERWALL_SECTORSTACK; - if (GLPortal::inupperstack) return; - this->portal = portal; - } - else if (fs->GetTexture(sector_t::floor)==skyflatnum) - { - SkyTexture(fs, sector_t::floor); - } - else if (fs->GetFloorReflect() > 0) - { - if (FIXED2DBL(viewz) <= fs->floorplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) return; - type=RENDERWALL_PLANEMIRROR; - planemirror = &fs->floorplane; - } - else return; + SkyPlane(fs, sector_t::ceiling, true); ztop[0]=zfloor[0]; ztop[1]=zfloor[1]; zbottom[0]=zbottom[1]=-32768.0f; - PutWall(0); + SkyPlane(fs, sector_t::floor, false); } //========================================================================== @@ -246,7 +219,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex ztop[0]=ztop[1]=32768.0f; zbottom[0]=zbottom[1]= FIXED2FLOAT(bs->ceilingplane.ZatPoint(v2) + seg->sidedef->GetTextureYOffset(side_t::mid)); - SkyTexture(fs, sector_t::ceiling); + SkyPlane(fs, sector_t::ceiling, false); return; } } @@ -273,7 +246,10 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex { FPortal *pfront = fs->portals[sector_t::ceiling]; FPortal *pback = bs->portals[sector_t::ceiling]; - if (pfront == NULL && (fs->GetCeilingReflect() == 0 || pfront == pback)) return; + if (fs->GetReflect(sector_t::floor) == 0 && (pfront == NULL || pfront == pback)) + { + return; + } // stacked sectors fixed_t fsc1=fs->ceilingplane.ZatPoint(v1); @@ -284,24 +260,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex zbottom[1]=FIXED2FLOAT(fsc2); } - FPortal *portal = fs->portals[sector_t::ceiling]; - if (portal != NULL) - { - type=RENDERWALL_SECTORSTACK; - if (GLPortal::inlowerstack) return; - this->portal = portal; - } - else if (fs->GetTexture(sector_t::ceiling)==skyflatnum) - { - SkyTexture(fs, sector_t::ceiling); - } - else // if (fs->ceiling_reflect != 0) - { - if (FIXED2DBL(viewz) >= fs->ceilingplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) return; - type=RENDERWALL_PLANEMIRROR; - planemirror = &fs->ceilingplane; - } - PutWall(0); + SkyPlane(fs, sector_t::ceiling, true); } @@ -353,7 +312,10 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver { FPortal *pfront = fs->portals[sector_t::floor]; FPortal *pback = bs->portals[sector_t::floor]; - if (pfront == NULL && (fs->GetFloorReflect() == 0 || pfront == pback)) return; + if (fs->GetReflect(sector_t::floor) == 0 && (pfront == NULL || pfront == pback)) + { + return; + } // stacked sectors fixed_t fsc1=fs->floorplane.ZatPoint(v1); @@ -364,22 +326,5 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver ztop[1]=FIXED2FLOAT(fsc2); } - FPortal *portal = fs->portals[sector_t::floor]; - if (portal != NULL) - { - type=RENDERWALL_SECTORSTACK; - if (GLPortal::inupperstack) return; - this->portal = portal; - } - else if (fs->GetTexture(sector_t::floor)==skyflatnum) - { - SkyTexture(fs, sector_t::floor); - } - else // if (fs->floor_reflect != 0) - { - if (FIXED2DBL(viewz) <= fs->floorplane.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy))) return; - type=RENDERWALL_PLANEMIRROR; - planemirror = &fs->floorplane; - } - PutWall(0); + SkyPlane(fs, sector_t::floor, true); } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 6b7744f8..58b81d68 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -163,12 +163,11 @@ private: void FloodPlane(int pass); - void MirrorPlane(secplane_t * plane, bool ceiling); - void SkyTexture(sector_t *sector, int plane); - + void SkyPlane(sector_t *sector, int plane, bool allowmirror); void SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2); void SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2); void SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2); + void Put3DWall(lightlist_t * lightlist, bool translucent); void SplitWall(sector_t * frontsector, bool translucent); void LightPass(); diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 0422fb2b..c242826c 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -502,17 +502,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) if (fs->GetTexture(sector_t::ceiling) == skyflatnum) { - portal = fs->portals[sector_t::ceiling]; - if (portal != NULL) - { - type=RENDERWALL_SECTORSTACK; - if (GLPortal::inlowerstack) goto floor; - this->portal = portal; - } - else - { - SkyTexture(fs, sector_t::ceiling); - } + SkyPlane(fs, sector_t::ceiling, false); } else { @@ -531,28 +521,17 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) if (gl_fixedcolormap) hi.colormap.GetFixedColormap(); horizon = &hi; + PutWall(0); } - PutWall(0); ztop[1] = ztop[0] = zbottom[0]; } -floor: if (viewz > fs->GetPlaneTexZ(sector_t::floor)) { zbottom[1] = zbottom[0] = FIXED2FLOAT(fs->GetPlaneTexZ(sector_t::floor)); if (fs->GetTexture(sector_t::floor) == skyflatnum) { - portal = fs->portals[sector_t::floor]; - if (portal != NULL) - { - type=RENDERWALL_SECTORSTACK; - if (GLPortal::inupperstack) return true; - this->portal = portal; - } - else - { - SkyTexture(fs, sector_t::floor); - } + SkyPlane(fs, sector_t::floor, false); } else { @@ -571,8 +550,8 @@ floor: if (gl_fixedcolormap) hi.colormap.GetFixedColormap(); horizon=&hi; + PutWall(0); } - PutWall(0); } return true; } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index be842592..c3c7ee26 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -374,7 +374,7 @@ void P_SerializeWorld (FArchive &arc) << desaturate; sec->ColorMap = GetSpecialLights (color, fade, desaturate); } - arc << sec->ceiling_reflect << sec->floor_reflect; + arc << sec->reflect[sector_t::ceiling] << sec->reflect[sector_t::floor]; } // do lines diff --git a/src/r_defs.h b/src/r_defs.h index 0e852c2a..1f268504 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -744,7 +744,7 @@ struct sector_t extsector_t * e; // This stores data that requires construction/destruction. Such data must not be copied by R_FakeFlat. // GL only stuff starts here - float ceiling_reflect, floor_reflect; + float reflect[2]; int dirtyframe[3]; // last frame this sector was marked dirty bool dirty; // marked for recalculation @@ -768,8 +768,7 @@ struct sector_t int ibocount; #endif - float GetFloorReflect() { return gl_plane_reflection_i? floor_reflect : 0; } - float GetCeilingReflect() { return gl_plane_reflection_i? ceiling_reflect : 0; } + float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; } bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); } enum diff --git a/src/version.h b/src/version.h index 29a30477..d21cb363 100644 --- a/src/version.h +++ b/src/version.h @@ -41,15 +41,15 @@ /** Lots of different version numbers **/ -#define DOTVERSIONSTR_NOREV "1.5.4" +#define DOTVERSIONSTR_NOREV "1.5.5" #define ZDVER_STRING "2.5.0" // The version string the user actually sees. #define DOTVERSIONSTR DOTVERSIONSTR_NOREV " (r" SVN_REVISION_STRING ") / ZDoom " ZDVER_STRING " (r" ZD_SVN_REVISION_STRING ")" // The version as seen in the Windows resource -#define RC_FILEVERSION 1,5,4,SVN_REVISION_NUMBER -#define RC_PRODUCTVERSION 1,5,4,0 +#define RC_FILEVERSION 1,5,5,SVN_REVISION_NUMBER +#define RC_PRODUCTVERSION 1,5,5,0 #define RC_FILEVERSION2 DOTVERSIONSTR #define RC_PRODUCTVERSION2 "1.5" From c61591aef1517923eeb0ed0ad19760751f151010 Mon Sep 17 00:00:00 2001 From: gez Date: Fri, 19 Nov 2010 09:53:59 +0000 Subject: [PATCH 39/82] * Updated to ZDoom r3010: - Add a SetCursor() call to I_SetCursor() when the pointer is within the window's client area to make the pointer change instant instead of waiting until the next mouse event. - Changed sprite-on-drawseg calculations to use untransformed coordinates. Build does it like this. I don't recall what Doom did. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1103 b0f79afe-0144-0410-b225-9a4edf0717df --- src/r_defs.h | 2 +- src/r_things.cpp | 4 ++-- src/win32/i_mouse.cpp | 2 +- src/win32/i_system.cpp | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 1f268504..86ff3071 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1139,7 +1139,7 @@ struct vissprite_t { short x1, x2; fixed_t cx; // for line side calculation - fixed_t gx, gy; // for fake floor clipping + fixed_t gx, gy; // for drawseg and fake floor clipping fixed_t gz, gzt; // global bottom / top for silhouette clipping fixed_t startfrac; // horizontal position of x1 fixed_t xscale, yscale; diff --git a/src/r_things.cpp b/src/r_things.cpp index 600354ce..4d40c04c 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2231,8 +2231,8 @@ void R_DrawSprite (vissprite_t *spr) } if (neardepth > spr->depth || (fardepth > spr->depth && // Check if sprite is in front of draw seg: - DMulScale24 (spr->depth - ds->cy, ds->cdx, ds->cdy, ds->cx - spr->cx) < 0)) - + DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x, + ds->curline->v1->x - spr->gx, ds->curline->v2->y - ds->curline->v1->y) <= 0)) { // seg is behind sprite, so draw the mid texture if it has one if (ds->maskedtexturecol != -1 || ds->bFogBoundary) diff --git a/src/win32/i_mouse.cpp b/src/win32/i_mouse.cpp index 873b9271..4ed34723 100644 --- a/src/win32/i_mouse.cpp +++ b/src/win32/i_mouse.cpp @@ -118,7 +118,6 @@ extern int BlockMouseMove; // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static bool NativeMouse; static EMouseMode MouseMode = MM_None; static FMouse *(*MouseFactory[])() = { @@ -130,6 +129,7 @@ static FMouse *(*MouseFactory[])() = // PUBLIC DATA DEFINITIONS ------------------------------------------------- FMouse *Mouse; +bool NativeMouse; bool CursorState; diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index b585be71..1da4855c 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -131,6 +131,7 @@ extern HANDLE StdOut; extern bool FancyStdOut; extern HINSTANCE g_hInst; extern FILE *Logfile; +extern bool NativeMouse; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -1214,6 +1215,23 @@ bool I_SetCursor(FTexture *cursorpic) cursor = LoadCursor(NULL, IDC_ARROW); } SetClassLongPtr(Window, GCLP_HCURSOR, (LONG_PTR)cursor); + if (NativeMouse) + { + POINT pt; + RECT client; + + // If the mouse pointer is within the window's client rect, set it now. + if (GetCursorPos(&pt) && GetClientRect(Window, &client) && + ClientToScreen(Window, (LPPOINT)&client.left) && + ClientToScreen(Window, (LPPOINT)&client.right)) + { + if (pt.x >= client.left && pt.x < client.right && + pt.y >= client.top && pt.y < client.bottom) + { + SetCursor(cursor); + } + } + } return true; } From 8e10ee5abb810f58d1fb8b56f50a4147b2b2e85c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 20 Nov 2010 14:25:56 +0000 Subject: [PATCH 40/82] - fixed: Creating more than 16 portals in a map caused memory corruption when the array of portal structures had to be reallocated. Replaced by an array of pointers. - fixed: Portals with zero lines in them must not be processed by the renderer. - version bump. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1104 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.h | 2 +- src/gl/data/gl_portaldata.cpp | 29 +++++++++++++++-------------- src/gl/data/gl_setup.cpp | 5 +++++ src/gl/scene/gl_portal.cpp | 11 ++++++----- src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_sky.cpp | 2 +- src/svnrevision.h | 4 ++-- src/version.h | 6 +++--- 8 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index 6d17a06a..42e12878 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -48,7 +48,7 @@ struct FPortal GLSectorStackPortal *GetGLPortal(); }; -extern TArray portals; +extern TArray portals; extern TArray currentmapsection; void gl_InitPortals(); diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index 3b1d75c6..b72e42bb 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -63,7 +63,7 @@ #include "gl/utility/gl_clock.h" #include "gl/gl_functions.h" -TArray portals; +TArray portals; //========================================================================== // @@ -498,12 +498,13 @@ void gl_InitPortals() // we only process portals that actually are in use. if (portalp[plane] == NULL) { - portalp[plane] = &portals[portals.Reserve(1)]; + portalp[plane] = new FPortal; portalp[plane]->origin = pt; portalp[plane]->glportal = NULL; portalp[plane]->plane = plane; portalp[plane]->xDisplacement = pt->x - pt->Mate->x; portalp[plane]->yDisplacement = pt->y - pt->Mate->y; + portals.Push(portalp[plane]); } portalp[plane]->AddSectorToPortal(§ors[i]); sectors[i].portals[plane] = portalp[plane]; @@ -522,10 +523,10 @@ void gl_InitPortals() // if the first vertex is duplicated at the end it'll save time in a time critical function // because that code does not need to check for wraparounds anymore. // Note: We cannot push an element of the array onto the array itself. This must be done in 2 steps - portals[i].Shape.Reserve(1); - portals[i].Shape.Last() = portals[i].Shape[0]; - portals[i].Shape.ShrinkToFit(); - portals[i].ClipAngles.Resize(portals[i].Shape.Size()); + portals[i]->Shape.Reserve(1); + portals[i]->Shape.Last() = portals[i]->Shape[0]; + portals[i]->Shape.ShrinkToFit(); + portals[i]->ClipAngles.Resize(portals[i]->Shape.Size()); } } @@ -534,20 +535,20 @@ CCMD(dumpportals) { for(unsigned i=0;ix/65536., portals[i].origin->y/65536., + double xdisp = portals[i]->xDisplacement/65536.; + double ydisp = portals[i]->yDisplacement/65536.; + Printf(PRINT_LOG, "Portal #%d, %s, stackpoint at (%f,%f), displacement = (%f,%f)\nShape:\n", i, portals[i]->plane==0? "floor":"ceiling", portals[i]->origin->x/65536., portals[i]->origin->y/65536., xdisp, ydisp); - for (unsigned j=0;jShape.Size(); j++) { - Printf(PRINT_LOG, "\t(%f,%f)\n", portals[i].Shape[j]->x/65536. + xdisp, portals[i].Shape[j]->y/65536. + ydisp); + Printf(PRINT_LOG, "\t(%f,%f)\n", portals[i]->Shape[j]->x/65536. + xdisp, portals[i]->Shape[j]->y/65536. + ydisp); } Printf(PRINT_LOG, "Coverage:\n"); for(int j=0;jrender_sector->FloorSkyBox : sub->render_sector->CeilingSkyBox; - if (pt == portals[i].origin) + ASkyViewpoint *pt = portals[i]->plane == 0? sub->render_sector->FloorSkyBox : sub->render_sector->CeilingSkyBox; + if (pt == portals[i]->origin) { Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", j, sub->render_sector->sectornum); for(unsigned k = 0;k< sub->numlines; k++) @@ -555,7 +556,7 @@ CCMD(dumpportals) Printf(PRINT_LOG, "(%.3f,%.3f), ", sub->firstline[k].v1->x/65536. + xdisp, sub->firstline[k].v1->y/65536. + ydisp); } Printf(PRINT_LOG, "\n\t\tCovered by subsectors:\n"); - FPortalCoverage *cov = &sub->portalcoverage[portals[i].plane]; + FPortalCoverage *cov = &sub->portalcoverage[portals[i]->plane]; for(int l = 0;l< cov->sscount; l++) { subsector_t *csub = &subsectors[cov->subsectors[l]]; diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index cf20203d..8b6b58b2 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -641,6 +641,11 @@ void gl_CleanLevelData() } } } + for(unsigned i=0;iGetName(), renderdepth, usequery); } - - p->RenderPortal(true, usequery); + if (p->lines.Size() > 0) + { + p->RenderPortal(true, usequery); + } delete p; } renderdepth--; @@ -530,7 +532,7 @@ bool GLPortal::RenderFirstSkyPortal(int recursion) for(unsigned i=portals.Size()-1;i>=0 && portals[i]!=NULL;i--) { p=portals[i]; - if (p->IsSky()) + if (p->lines.Size() > 0 && p->IsSky()) { // Cannot clear the depth buffer inside a portal recursion if (recursion && p->NeedDepthBuffer()) continue; @@ -545,9 +547,8 @@ bool GLPortal::RenderFirstSkyPortal(int recursion) if (best) { - best->RenderPortal(false, false); portals.Delete(bestindex); - + best->RenderPortal(false, false); delete best; return true; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 96e66e07..ed17184f 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -313,6 +313,7 @@ void FGLRenderer::CreateScene() ProcessAll.Clock(); // clip the scene and fill the drawlists + for(unsigned i=0;iglportal = NULL; gl_spriteindex=0; Bsp.Clock(); gl_RenderBSPNode (nodes + numnodes - 1); @@ -851,7 +852,6 @@ void FGLRenderer::ProcessScene(bool toscreen) int mapsection = R_PointInSubsector(viewx, viewy)->mapsection; memset(¤tmapsection[0], 0, currentmapsection.Size()); currentmapsection[mapsection>>3] |= 1 << (mapsection & 7); - for(unsigned i=0;iportals[plane]; if (portal != NULL) { - type=RENDERWALL_SECTORSTACK; if (GLPortal::instack[1-plane]) return; + type=RENDERWALL_SECTORSTACK; this->portal = portal; } else if (sector->GetTexture(plane)==skyflatnum) diff --git a/src/svnrevision.h b/src/svnrevision.h index 2a6b13bc..41c746c6 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3008" -#define ZD_SVN_REVISION_NUMBER 3008 +#define ZD_SVN_REVISION_STRING "3010" +#define ZD_SVN_REVISION_NUMBER 3010 diff --git a/src/version.h b/src/version.h index d21cb363..08cb9596 100644 --- a/src/version.h +++ b/src/version.h @@ -41,15 +41,15 @@ /** Lots of different version numbers **/ -#define DOTVERSIONSTR_NOREV "1.5.5" +#define DOTVERSIONSTR_NOREV "1.5.6" #define ZDVER_STRING "2.5.0" // The version string the user actually sees. #define DOTVERSIONSTR DOTVERSIONSTR_NOREV " (r" SVN_REVISION_STRING ") / ZDoom " ZDVER_STRING " (r" ZD_SVN_REVISION_STRING ")" // The version as seen in the Windows resource -#define RC_FILEVERSION 1,5,5,SVN_REVISION_NUMBER -#define RC_PRODUCTVERSION 1,5,5,0 +#define RC_FILEVERSION 1,5,6,SVN_REVISION_NUMBER +#define RC_PRODUCTVERSION 1,5,6,0 #define RC_FILEVERSION2 DOTVERSIONSTR #define RC_PRODUCTVERSION2 "1.5" From 0935392d388c5738d02036fd071003be34279451 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Nov 2010 08:08:22 +0000 Subject: [PATCH 41/82] - fixed: One-sided walls bordering a reflective surface were handled incorrectly. - fixed: reflective ceilings checked the floor plane on two-sided lines. - changed: Don't add lines to a reflective floor portal which have the same reflective floor portal on both sides. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1106 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_sky.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 54a27a89..18fc6ff7 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -180,7 +180,7 @@ void GLWall::SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2) ztop[0]=zfloor[0]; ztop[1]=zfloor[1]; zbottom[0]=zbottom[1]=-32768.0f; - SkyPlane(fs, sector_t::floor, false); + SkyPlane(fs, sector_t::floor, true); } //========================================================================== @@ -246,7 +246,17 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex { FPortal *pfront = fs->portals[sector_t::ceiling]; FPortal *pback = bs->portals[sector_t::ceiling]; - if (fs->GetReflect(sector_t::floor) == 0 && (pfront == NULL || pfront == pback)) + float frontreflect = fs->GetReflect(sector_t::ceiling); + if (frontreflect > 0) + { + float backreflect = bs->GetReflect(sector_t::ceiling); + if (backreflect > 0 && bs->ceilingplane.d == fs->ceilingplane.d) + { + // Don't add intra-portal line to the portal. + return; + } + } + else if (pfront == NULL || pfront == pback) { return; } @@ -312,7 +322,17 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver { FPortal *pfront = fs->portals[sector_t::floor]; FPortal *pback = bs->portals[sector_t::floor]; - if (fs->GetReflect(sector_t::floor) == 0 && (pfront == NULL || pfront == pback)) + float frontreflect = fs->GetReflect(sector_t::floor); + if (frontreflect > 0) + { + float backreflect = bs->GetReflect(sector_t::floor); + if (backreflect > 0 && bs->floorplane.d == fs->floorplane.d) + { + // Don't add intra-portal line to the portal. + return; + } + } + else if (pfront == NULL || pfront == pback) { return; } From bbb9b758367a69a3be5b94e3448fd2031534264f Mon Sep 17 00:00:00 2001 From: gez Date: Mon, 22 Nov 2010 00:03:43 +0000 Subject: [PATCH 42/82] - Applied crazymykl's patch to improve GLSL compatibility with Mesa. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1107 b0f79afe-0144-0410-b225-9a4edf0717df --- wadsrc/static/shaders/glsl/main.fp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 551ef1f0..07c5628b 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -66,7 +66,7 @@ vec4 getLightColor(float fogdist, float fogfactor) // if (fogenabled > 0) { - #if !defined NO_SM4 || defined DOOMLIGHT + #if !defined(NO_SM4) || defined(DOOMLIGHT) // special lighting mode 'Doom' not available on older cards for performance reasons. if (fogdist < fogparm.y) { @@ -170,7 +170,7 @@ void main() { fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); } - #elif !defined FOG_RADIAL + #elif !defined(FOG_RADIAL) fogdist = pixelpos.w; #else fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); From b1620e72532242ee2a55dbe614795c4a85616169 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 Nov 2010 21:11:30 +0000 Subject: [PATCH 43/82] - fixed: vertex_t needs a constructor so that the GL specific fields get initialized reliably. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1109 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_sky.cpp | 1 + src/r_defs.h | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 18fc6ff7..f69695b1 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -348,3 +348,4 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver SkyPlane(fs, sector_t::floor, true); } + diff --git a/src/r_defs.h b/src/r_defs.h index 86ff3071..ab55f0de 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -83,6 +83,17 @@ struct vertex_t sector_t ** sectors; float * heightlist; + vertex_t() + { + x = y = 0; + fx = fy = 0; + viewangle = 0; + dirty = true; + numheights = numsectors = 0; + sectors = NULL; + heightlist = NULL; + } + bool operator== (const vertex_t &other) { return x == other.x && y == other.y; From e8c4d8b87a0c8f6d759ce4120e42c8b04aeab128 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Nov 2010 09:45:47 +0000 Subject: [PATCH 44/82] - fixed: When restrzcturing the portal code the initialization of the GLFlat::stack was lost. - removed some dead code. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1110 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_flats.cpp | 4 ++-- src/gl/scene/gl_scene.cpp | 19 ------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 876ef5aa..3174e5ca 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -602,7 +602,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = GetFloorLight(frontsector); Colormap=frontsector->ColorMap; - if (frontsector->portals[sector_t::floor] != NULL) + if ((stack = (frontsector->portals[sector_t::floor] != NULL))) { gl_drawinfo->AddFloorStack(sector); alpha = frontsector->GetAlpha(sector_t::floor)/65536.0f; @@ -650,7 +650,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = GetCeilingLight(frontsector); Colormap=frontsector->ColorMap; - if (frontsector->portals[sector_t::ceiling] != NULL) + if ((stack = (frontsector->portals[sector_t::ceiling] != NULL))) { gl_drawinfo->AddCeilingStack(sector); alpha = frontsector->GetAlpha(sector_t::ceiling)/65536.0f; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index ed17184f..75186fc3 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -956,9 +956,6 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo //----------------------------------------------------------------------------- static FRandom pr_glhom; EXTERN_CVAR(Int, r_clearbuffer) -CVAR(Bool, gl_testdl, false, 0) -static int dl = -1; -static int indl = 0; void FGLRenderer::RenderView (player_t* player) { @@ -1040,22 +1037,6 @@ void FGLRenderer::RenderView (player_t* player) TThinkerIterator it(STAT_DLIGHT); GLRenderer->mLightCount = ((it.Next()) != NULL); - if (gl_testdl) - { - if (dl == -1) - { - dl = glGenLists(1); - glNewList(dl, GL_COMPILE_AND_EXECUTE); - indl = true; - } - else - { - glCallList(dl); - All.Unclock(); - return; - } - } - sector_t * viewsector = RenderViewpoint(player->camera, NULL, FieldOfView * 360.0f / FINEANGLES, ratio, fovratio, true, true); EndDrawScene(viewsector); From 329d2c32cd1f5e9f3dd094671d4c058fe2d6039c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Nov 2010 11:03:07 +0000 Subject: [PATCH 45/82] - missed some dead code during last cleanup. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1111 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_scene.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 75186fc3..8fb9fc33 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -1040,12 +1040,6 @@ void FGLRenderer::RenderView (player_t* player) sector_t * viewsector = RenderViewpoint(player->camera, NULL, FieldOfView * 360.0f / FINEANGLES, ratio, fovratio, true, true); EndDrawScene(viewsector); - if (gl_testdl && indl) - { - indl = false; - glEndList(); - } - All.Unclock(); } From d48dad95675d49905fa00ef2fdf9cdbd78ae9e0c Mon Sep 17 00:00:00 2001 From: gez Date: Sun, 28 Nov 2010 18:13:38 +0000 Subject: [PATCH 46/82] - Fixed: iwadinfo.txt had the wrong base MAPINFO for Urban Brawl. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1112 b0f79afe-0144-0410-b225-9a4edf0717df --- wadsrc/static/iwadinfo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index 2bf5f836..efdf836a 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -25,7 +25,7 @@ IWad Name = "Action Doom 2: Urban Brawl" Game = "Doom" Config = "UrbanBrawl" - Mapinfo = "mapinfo/doom2.txt" + Mapinfo = "mapinfo/urbanbrawl.txt" MustContain = "MAP01", "AD2LIB" BannerColors = "a8 a8 00", "a8 00 00" } From 9aefd4cddc3339a329b09e934cafe4e2ed76e2fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 30 Nov 2010 08:39:31 +0000 Subject: [PATCH 47/82] - Update to ZDoom r3013: * Added code submission for printing secret information. * Added missing TRXTCOLOR_CYAN #define. * Changed bridge things to be completely immobile towards sector plane movement. This problem again reared its ugly head in 007LTSD where the oversized bridges got messed up by some opening doors and lowering lifts. Now any plane trying to move such a thing will get blocked. Moving these things by other means still works normally, of course * Added some fudging to make sectors that are neighboring a portal plane but share the same texture properties actual parts of the portal. This is only done when portals are defined with portal things. This was necessary to preserve an effect that depended on incomplete checks in the renderer that could not be preserved with the implementation of linedef based portals. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1113 b0f79afe-0144-0410-b225-9a4edf0717df --- src/c_cmds.cpp | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ src/p_map.cpp | 29 +++++++++--- src/p_spec.cpp | 80 +++++++++++++++++++++++++++++++++ src/v_text.h | 1 + 4 files changed, 224 insertions(+), 6 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index f3cb4095..12055ebc 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -68,6 +68,8 @@ #include "p_setup.h" #include "cmdlib.h" #include "d_net.h" +#include "v_text.h" +#include "p_lnspec.h" extern FILE *Logfile; extern bool insave; @@ -929,6 +931,7 @@ CCMD(nextsecret) // // //----------------------------------------------------------------------------- + CCMD(currentpos) { AActor *mo = players[consoleplayer].mo; @@ -936,4 +939,121 @@ CCMD(currentpos) FIXED2FLOAT(mo->x), FIXED2FLOAT(mo->y), FIXED2FLOAT(mo->z), mo->angle/float(ANGLE_1), FIXED2FLOAT(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel); } +//----------------------------------------------------------------------------- +// +// Print secret info (submitted by Karl Murks) +// +//----------------------------------------------------------------------------- +static void PrintSecretString(const char *string, bool thislevel) +{ + const char *colstr = thislevel? TEXTCOLOR_YELLOW : TEXTCOLOR_CYAN; + if (string != NULL) + { + if (*string == '$') + { + if (string[1] == 'S' || string[1] == 's') + { + long secnum = strtol(string+2, (char**)&string, 10); + if (*string == ';') string++; + if (thislevel && secnum >= 0 && secnum < numsectors) + { + if (sectors[secnum].secretsector) + { + if ((sectors[secnum].special & SECRET_MASK)) colstr = TEXTCOLOR_RED; + else colstr = TEXTCOLOR_GREEN; + } + else colstr = TEXTCOLOR_ORANGE; + } + } + else if (string[1] == 'T' || string[1] == 't') + { + long tid = strtol(string+2, (char**)&string, 10); + if (*string == ';') string++; + FActorIterator it(tid); + AActor *actor; + bool foundone = false; + if (thislevel) + { + while ((actor = it.Next())) + { + if (!actor->IsKindOf(PClass::FindClass("SecretTrigger"))) continue; + foundone = true; + break; + } + } + if (foundone) colstr = TEXTCOLOR_YELLOW; + else colstr = TEXTCOLOR_RED; + } + } + FBrokenLines *brok = V_BreakLines(ConFont, screen->GetWidth()*95/100, string); + + for (int k = 0; brok[k].Width >= 0; k++) + { + Printf("%s%s\n", colstr, brok[k].Text.GetChars()); + } + V_FreeBrokenLines(brok); + } +} + +//============================================================================ +// +// Print secret hints +// +//============================================================================ + +CCMD(secret) +{ + const char *mapname = argv.argc() < 2? level.mapname : argv[1]; + bool thislevel = !stricmp(mapname, level.mapname); + bool foundsome = false; + + int lumpno=Wads.CheckNumForName("SECRETS"); + if (lumpno < 0) return; + + FWadLump lump = Wads.OpenLumpNum(lumpno); + FString maphdr; + maphdr.Format("[%s]", mapname); + + FString linebuild; + char readbuffer[1024]; + bool inlevel = false; + + while (lump.Gets(readbuffer, 1024)) + { + if (!inlevel) + { + if (readbuffer[0] == '[') + { + inlevel = !strnicmp(readbuffer, maphdr, maphdr.Len()); + if (!foundsome) + { + FString levelname; + level_info_t *info = FindLevelInfo(mapname); + levelname.Format("%s - %s\n", mapname, info->LevelName); + size_t llen = levelname.Len() - 1; + for(size_t ii=0; iiflags2 & MF2_PASSMOBJ) || - (!(intersect->flags3 & MF3_ISMONSTER) && - intersect->Mass > mymass)) - { // Can't push things more massive than ourself + (!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) || + (intersect->flags4 & MF4_ACTLIKEBRIDGE) + ) + { + // Can't push bridges or things more massive than ourself return 2; } fixed_t oldz = intersect->z; @@ -4779,9 +4781,11 @@ int P_PushDown (AActor *thing, FChangePosition *cpos) { AActor *intersect = intersectors[firstintersect]; if (!(intersect->flags2 & MF2_PASSMOBJ) || - (!(intersect->flags3 & MF3_ISMONSTER) && - intersect->Mass > mymass)) - { // Can't push things more massive than ourself + (!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) || + (intersect->flags4 & MF4_ACTLIKEBRIDGE) + ) + { + // Can't push bridges or things more massive than ourself return 2; } fixed_t oldz = intersect->z; @@ -4813,6 +4817,7 @@ void PIT_FloorDrop (AActor *thing, FChangePosition *cpos) P_AdjustFloorCeil (thing, cpos); if (oldfloorz == thing->floorz) return; + if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things if (thing->velz == 0 && (!(thing->flags & MF_NOGRAVITY) || @@ -4856,6 +4861,11 @@ void PIT_FloorRaise (AActor *thing, FChangePosition *cpos) if (thing->z <= thing->floorz || (!(thing->flags & MF_NOGRAVITY) && (thing->flags2 & MF2_FLOATBOB))) { + if (thing->flags4 & MF4_ACTLIKEBRIDGE) + { + cpos->nofit = true; + return; // do not move bridge things + } intersectors.Clear (); fixed_t oldz = thing->z; if (!(thing->flags2 & MF2_FLOATBOB)) @@ -4898,6 +4908,11 @@ void PIT_CeilingLower (AActor *thing, FChangePosition *cpos) if (thing->z + thing->height > thing->ceilingz) { + if (thing->flags4 & MF4_ACTLIKEBRIDGE) + { + cpos->nofit = true; + return; // do not move bridge things + } intersectors.Clear (); fixed_t oldz = thing->z; if (thing->ceilingz - thing->height >= thing->floorz) @@ -4935,6 +4950,8 @@ void PIT_CeilingRaise (AActor *thing, FChangePosition *cpos) { bool isgood = P_AdjustFloorCeil (thing, cpos); + if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things + // For DOOM compatibility, only move things that are inside the floor. // (or something else?) Things marked as hanging from the ceiling will // stay where they are. diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 0ba2f01d..bdd6820f 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -888,6 +888,72 @@ static void SetupCeilingPortal (AStackPoint *point) } } +static bool SpreadCeilingPortal(AStackPoint *pt, fixed_t alpha, sector_t *sector) +{ + bool fail = false; + sector->validcount = validcount; + for(int i=0; ilinecount; i++) + { + line_t *line = sector->lines[i]; + sector_t *backsector = sector == line->frontsector? line->backsector : line->frontsector; + if (line->backsector == line->frontsector) continue; + if (backsector == NULL) { fail = true; continue; } + if (backsector->validcount == validcount) continue; + if (backsector->CeilingSkyBox == pt) continue; + + // Check if the backside would map to the same visplane + if (backsector->CeilingSkyBox != NULL) { fail = true; continue; } + if (backsector->ceilingplane != sector->ceilingplane) { fail = true; continue; } + if (backsector->lightlevel != sector->lightlevel) { fail = true; continue; } + if (backsector->GetTexture(sector_t::ceiling) != sector->GetTexture(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetXOffset(sector_t::ceiling) != sector->GetXOffset(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetYOffset(sector_t::ceiling) != sector->GetYOffset(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetXScale(sector_t::ceiling) != sector->GetXScale(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetYScale(sector_t::ceiling) != sector->GetYScale(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetAngle(sector_t::ceiling) != sector->GetAngle(sector_t::ceiling)) { fail = true; continue; } + if (SpreadCeilingPortal(pt, alpha, backsector)) { fail = true; continue; } + } + if (!fail) + { + sector->CeilingSkyBox = pt; + sector->SetAlpha(sector_t::ceiling, alpha); + } + return fail; +} + +static bool SpreadFloorPortal(AStackPoint *pt, fixed_t alpha, sector_t *sector) +{ + bool fail = false; + sector->validcount = validcount; + for(int i=0; ilinecount; i++) + { + line_t *line = sector->lines[i]; + sector_t *backsector = sector == line->frontsector? line->backsector : line->frontsector; + if (line->backsector == line->frontsector) continue; + if (backsector == NULL) { fail = true; continue; } + if (backsector->validcount == validcount) continue; + if (backsector->FloorSkyBox == pt) continue; + + // Check if the backside would map to the same visplane + if (backsector->FloorSkyBox != NULL) { fail = true; continue; } + if (backsector->floorplane != sector->ceilingplane) { fail = true; continue; } + if (backsector->lightlevel != sector->lightlevel) { fail = true; continue; } + if (backsector->GetTexture(sector_t::floor) != sector->GetTexture(sector_t::floor)) { fail = true; continue; } + if (backsector->GetXOffset(sector_t::floor) != sector->GetXOffset(sector_t::floor)) { fail = true; continue; } + if (backsector->GetYOffset(sector_t::floor) != sector->GetYOffset(sector_t::floor)) { fail = true; continue; } + if (backsector->GetXScale(sector_t::floor) != sector->GetXScale(sector_t::floor)) { fail = true; continue; } + if (backsector->GetYScale(sector_t::floor) != sector->GetYScale(sector_t::floor)) { fail = true; continue; } + if (backsector->GetAngle(sector_t::floor) != sector->GetAngle(sector_t::floor)) { fail = true; continue; } + if (SpreadFloorPortal(pt, alpha, backsector)) { fail = true; continue; } + } + if (!fail) + { + sector->FloorSkyBox = pt; + sector->SetAlpha(sector_t::floor, alpha); + } + return fail; +} + void P_SetupPortals() { TThinkerIterator it; @@ -936,6 +1002,20 @@ void P_SetupPortals() } } } + validcount++; + // Some fudging to preserve an unintended 'portal bleeding' effect caused by incomplete checks in the rendering code. + // Due to the addition of linedef-based portals this effect no longer works. + for(int i=0;ibAlways && sectors[i].validcount != validcount) + { + SpreadCeilingPortal(barrier_cast(sectors[i].CeilingSkyBox), sectors[i].GetAlpha(sector_t::ceiling), §ors[i]); + } + if (sectors[i].FloorSkyBox != NULL && sectors[i].FloorSkyBox->bAlways && sectors[i].validcount != validcount) + { + SpreadFloorPortal(barrier_cast(sectors[i].FloorSkyBox), sectors[i].GetAlpha(sector_t::floor), §ors[i]); + } + } } inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t alpha) diff --git a/src/v_text.h b/src/v_text.h index 494ebb31..29dfa627 100644 --- a/src/v_text.h +++ b/src/v_text.h @@ -67,6 +67,7 @@ struct FBrokenLines #define TEXTCOLOR_DARKBROWN "\034S" #define TEXTCOLOR_PURPLE "\034T" #define TEXTCOLOR_DARKGRAY "\034U" +#define TEXTCOLOR_CYAN "\034V" #define TEXTCOLOR_NORMAL "\034-" #define TEXTCOLOR_BOLD "\034+" From 58fc991d57d97b4551d7b42fc7249aeb1d3dfa6b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 30 Nov 2010 09:17:52 +0000 Subject: [PATCH 48/82] - fixed: Drawing multiple portals could overwrite some necessary occlusion info to render portals properly. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1114 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_portal.cpp | 26 ++++++++++++++++++++++++-- src/gl/scene/gl_portal.h | 3 +++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 4b6e111c..6eeacd99 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -561,6 +561,7 @@ bool GLPortal::RenderFirstSkyPortal(int recursion) // FindPortal // //----------------------------------------------------------------------------- + GLPortal * GLPortal::FindPortal(const void * src) { int i=portals.Size()-1; @@ -570,6 +571,23 @@ GLPortal * GLPortal::FindPortal(const void * src) } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void GLPortal::SaveMapSection() +{ + savedmapsection.Resize(currentmapsection.Size()); + memcpy(&savedmapsection[0], ¤tmapsection[0], currentmapsection.Size()); + memset(¤tmapsection[0], 0, currentmapsection.Size()); +} + +void GLPortal::RestoreMapSection() +{ + memcpy(¤tmapsection[0], &savedmapsection[0], currentmapsection.Size()); +} //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -627,7 +645,8 @@ void GLSkyboxPortal::DrawContents() ClearClipper(); int mapsection = R_PointInSubsector(viewx, viewy)->mapsection; - memset(¤tmapsection[0], 0, currentmapsection.Size()); + + SaveMapSection(); currentmapsection[mapsection>>3] |= 1 << (mapsection & 7); GLRenderer->DrawScene(); @@ -638,6 +657,8 @@ void GLSkyboxPortal::DrawContents() PlaneMirrorMode=old_pm; extralight = saved_extralight; + + RestoreMapSection(); } //----------------------------------------------------------------------------- @@ -678,7 +699,6 @@ static BYTE SetCoverage(void *node) void GLSectorStackPortal::SetupCoverage() { - memset(¤tmapsection[0], 0, currentmapsection.Size()); for(unsigned i=0; iplane != -1) instack[origin->plane]++; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); + SaveMapSection(); SetupCoverage(); ClearClipper(); GLRenderer->DrawScene(); + RestoreMapSection(); if (origin->plane != -1) instack[origin->plane]--; } diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 8746173a..da99838e 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -103,6 +103,7 @@ private: area_t savedviewarea; unsigned char clipsave; GLPortal *NextPortal; + TArray savedmapsection; protected: TArray lines; @@ -121,6 +122,8 @@ protected: virtual bool NeedDepthBuffer() { return true; } void ClearScreen(); virtual const char *GetName() = 0; + void SaveMapSection(); + void RestoreMapSection(); public: From 398972dfc0becddf470e4886f6735f34cba97621 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 30 Nov 2010 09:36:50 +0000 Subject: [PATCH 49/82] - fixed: Normal skyboxes should not block spawning of a portal. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1115 b0f79afe-0144-0410-b225-9a4edf0717df --- src/p_spec.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index bdd6820f..eeb58d0c 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -867,7 +867,7 @@ static void SetupFloorPortal (AStackPoint *point) NActorIterator it (NAME_LowerStackLookOnly, point->tid); sector_t *Sector = point->Sector; Sector->FloorSkyBox = static_cast(it.Next()); - if (Sector->FloorSkyBox != NULL) + if (Sector->FloorSkyBox != NULL || !Sector->FloorSkyBox->bAlways) { Sector->FloorSkyBox->Mate = point; if (Sector->GetAlpha(sector_t::floor) == OPAQUE) @@ -880,7 +880,7 @@ static void SetupCeilingPortal (AStackPoint *point) NActorIterator it (NAME_UpperStackLookOnly, point->tid); sector_t *Sector = point->Sector; Sector->CeilingSkyBox = static_cast(it.Next()); - if (Sector->CeilingSkyBox != NULL) + if (Sector->CeilingSkyBox != NULL || !Sector->CeilingSkyBox->bAlways) { Sector->CeilingSkyBox->Mate = point; if (Sector->GetAlpha(sector_t::ceiling) == OPAQUE) @@ -1023,7 +1023,7 @@ inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t // plane: 0=floor, 1=ceiling, 2=both if (plane > 0) { - if (sector->CeilingSkyBox == NULL) + if (sector->CeilingSkyBox == NULL || !sector->CeilingSkyBox->bAlways) { sector->CeilingSkyBox = portal; if (sector->GetAlpha(sector_t::ceiling) == OPAQUE) @@ -1032,7 +1032,10 @@ inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t } if (plane == 2 || plane == 0) { - if (sector->FloorSkyBox == NULL) sector->FloorSkyBox = portal; + if (sector->FloorSkyBox == NULL || !sector->FloorSkyBox->bAlways) + { + sector->FloorSkyBox = portal; + } if (sector->GetAlpha(sector_t::floor) == OPAQUE) sector->SetAlpha(sector_t::floor, alpha); } From ce708b38011d95940f6885222bf1d1756cb5bd3f Mon Sep 17 00:00:00 2001 From: gez Date: Thu, 2 Dec 2010 11:18:30 +0000 Subject: [PATCH 50/82] * Updated to ZDoom r3016: - Increase MAX_SKYBOX_PLANES to 1000. - Fixed: The code that set DIntermissionController::CurrentIntermission was missing a write barrier. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1116 b0f79afe-0144-0410-b225-9a4edf0717df --- src/intermission/intermission.cpp | 1 + src/r_plane.cpp | 2 +- src/svnrevision.h | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 0b8afa1e..f0d30857 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -838,6 +838,7 @@ void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, BYTE stat viewactive = false; automapactive = false; DIntermissionController::CurrentIntermission = new DIntermissionController(desc, deleteme, state); + GC::WriteBarrier(DIntermissionController::CurrentIntermission); } diff --git a/src/r_plane.cpp b/src/r_plane.cpp index abf813fd..eaa3d4b4 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -75,7 +75,7 @@ planefunction_t ceilingfunc; #define MAXVISPLANES 128 /* must be a power of 2 */ // Avoid infinite recursion with stacked sectors by limiting them. -#define MAX_SKYBOX_PLANES 100 +#define MAX_SKYBOX_PLANES 1000 // [RH] Allocate one extra for sky box planes. static visplane_t *visplanes[MAXVISPLANES+1]; // killough diff --git a/src/svnrevision.h b/src/svnrevision.h index 41c746c6..2a1ff8c7 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3010" -#define ZD_SVN_REVISION_NUMBER 3010 +#define ZD_SVN_REVISION_STRING "3016" +#define ZD_SVN_REVISION_NUMBER 3016 From eae3efdb2a5d19c5e9c60a0e96875a2a3a04858f Mon Sep 17 00:00:00 2001 From: gez Date: Thu, 2 Dec 2010 14:03:18 +0000 Subject: [PATCH 51/82] * Updated to ZDoom r3017: - Fixed: A new episode definition for a map that already had one defined did not replace the old definition. - Fixed: Skipping the skill menu did not work because it checked the number of episodes, not skills. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1117 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_mapinfo.cpp | 8 +++++++- src/menu/menudef.cpp | 2 +- src/svnrevision.h | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 84b6aa48..adf0b2cd 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1626,7 +1626,13 @@ void FMapInfoParser::ParseEpisodeInfo () } else { - FEpisode *epi = &AllEpisodes[AllEpisodes.Reserve(1)]; + // Only allocate a new entry if this doesn't replace an existing episode. + if (i >= AllEpisodes.Size()) + { + i = AllEpisodes.Reserve(1); + } + + FEpisode *epi = &AllEpisodes[i]; epi->mEpisodeMap = map; epi->mEpisodeName = name; diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index a751caf5..79ae99a2 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -1327,7 +1327,7 @@ void M_StartupSkillMenu(FGameStartup *gs) } if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) { - ld->mAutoselect = firstitem + MIN(2u, AllEpisodes.Size()-1); + ld->mAutoselect = firstitem + MIN(2u, AllSkills.Size()-1); } else { diff --git a/src/svnrevision.h b/src/svnrevision.h index 2a1ff8c7..f48714a0 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3016" -#define ZD_SVN_REVISION_NUMBER 3016 +#define ZD_SVN_REVISION_STRING "3017" +#define ZD_SVN_REVISION_NUMBER 3017 From 26dbf10bb8d59017dc96e0d3faa9c83613ce2a38 Mon Sep 17 00:00:00 2001 From: gez Date: Thu, 2 Dec 2010 16:08:07 +0000 Subject: [PATCH 52/82] * Updated to ZDoom r3018: - Restore old portal checks for Action Doom 2 (as a hidden compatibility option.) git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1118 b0f79afe-0144-0410-b225-9a4edf0717df --- src/compatibility.cpp | 8 +++++++- src/d_iwad.cpp | 1 + src/doomdef.h | 1 + src/p_spec.cpp | 3 +++ src/r_plane.cpp | 33 ++++++++++++++++++++------------- src/svnrevision.h | 4 ++-- wadsrc/static/iwadinfo.txt | 1 + 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 880f8878..bfd5ae32 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -90,6 +90,7 @@ static FCompatOption Options[] = { "resetplayerspeed", 0, BCOMPATF_RESETPLAYERSPEED }, { "vileghosts", 0, BCOMPATF_VILEGHOSTS }, { "ignoreteleporttags", 0, BCOMPATF_BADTELEPORTERS }, + { "oldportals", 0, BCOMPATF_BADPORTALS }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, 0 }, @@ -280,7 +281,12 @@ void CheckCompatibility(MapData *map) ib_compatflags = 0; ii_compatparams = -1; } - + else if (Wads.GetLumpFile(map->lumpnum) == 1 && (gameinfo.flags & GI_COMPATPORTAL)) + { + ii_compatflags = 0; + ib_compatflags = BCOMPATF_BADPORTALS; + ii_compatparams = -1; + } else { map->GetChecksum(md5.Bytes); diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 6fd42a62..123f33f7 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -174,6 +174,7 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize) else if(sc.Compare("Extended")) iwad->flags |= GI_MENUHACK_EXTENDED; else if(sc.Compare("Shorttex")) iwad->flags |= GI_COMPATSHORTTEX; else if(sc.Compare("Stairs")) iwad->flags |= GI_COMPATSTAIRS; + else if(sc.Compare("Portals")) iwad->flags |= GI_BADPORTALS; else sc.ScriptError(NULL); } while (sc.CheckString(",")); diff --git a/src/doomdef.h b/src/doomdef.h index cad56d64..748f2df4 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -342,6 +342,7 @@ enum BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' radius and height aren't restored properly when resurrected. BCOMPATF_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials + BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior }; // phares 3/20/98: diff --git a/src/p_spec.cpp b/src/p_spec.cpp index eeb58d0c..a2e09d34 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -975,6 +975,9 @@ void P_SetupPortals() points.Push(pt); } + // Maps using undefined portal hacks may not benefit from portal optimizations. + if (ib_compatflags & BCOMPATF_BADPORTALS) return; + for(unsigned i=0;ispecial1 == 0 && points[i]->Mate != NULL) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index eaa3d4b4..3fa6bdf7 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -582,20 +582,27 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl check->viewx == stacked_viewx && check->viewy == stacked_viewy && check->viewz == stacked_viewz && - check->alpha == alpha && - (alpha == 0 || // if alpha is > 0 everything needs to be checked - (plane == check->height && - picnum == check->picnum && - lightlevel == check->lightlevel && - xoffs == check->xoffs && // killough 2/28/98: Add offset checks - yoffs == check->yoffs && - basecolormap == check->colormap && // [RH] Add more checks - xscale == check->xscale && - yscale == check->yscale && - angle == check->angle + ( + // headache inducing logic... :( + (ib_compatflags & BCOMPATF_BADPORTALS) || + ( + check->alpha == alpha && + (alpha == 0 || // if alpha is > 0 everything needs to be checked + (plane == check->height && + picnum == check->picnum && + lightlevel == check->lightlevel && + xoffs == check->xoffs && // killough 2/28/98: Add offset checks + yoffs == check->yoffs && + basecolormap == check->colormap && // [RH] Add more checks + xscale == check->xscale && + yscale == check->yscale && + angle == check->angle + ) + ) && + check->viewangle == stacked_angle ) - ) && - check->viewangle == stacked_angle) + ) + ) { return check; } diff --git a/src/svnrevision.h b/src/svnrevision.h index f48714a0..8a4e886a 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3017" -#define ZD_SVN_REVISION_NUMBER 3017 +#define ZD_SVN_REVISION_STRING "3018" +#define ZD_SVN_REVISION_NUMBER 3018 diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index efdf836a..7a94f244 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -26,6 +26,7 @@ IWad Game = "Doom" Config = "UrbanBrawl" Mapinfo = "mapinfo/urbanbrawl.txt" + Compatibility = "Portals" MustContain = "MAP01", "AD2LIB" BannerColors = "a8 a8 00", "a8 00 00" } From 8de8b0de2e9fb6b763b867718e16ef644509e06b Mon Sep 17 00:00:00 2001 From: gez Date: Thu, 2 Dec 2010 17:38:48 +0000 Subject: [PATCH 53/82] * Updated to ZDoom r3019: - Fix last commit git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1119 b0f79afe-0144-0410-b225-9a4edf0717df --- src/d_iwad.cpp | 2 +- src/gi.h | 3 ++- src/svnrevision.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 123f33f7..b02407b1 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -174,7 +174,7 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize) else if(sc.Compare("Extended")) iwad->flags |= GI_MENUHACK_EXTENDED; else if(sc.Compare("Shorttex")) iwad->flags |= GI_COMPATSHORTTEX; else if(sc.Compare("Stairs")) iwad->flags |= GI_COMPATSTAIRS; - else if(sc.Compare("Portals")) iwad->flags |= GI_BADPORTALS; + else if(sc.Compare("Portals")) iwad->flags |= GI_COMPATPORTAL; else sc.ScriptError(NULL); } while (sc.CheckString(",")); diff --git a/src/gi.h b/src/gi.h index 42405262..645f5d3b 100644 --- a/src/gi.h +++ b/src/gi.h @@ -46,7 +46,8 @@ #define GI_COMPATSTAIRS 0x00000020 // same for stairbuilding #define GI_COMPATPOLY1 0x00000040 // Hexen's MAP36 needs old polyobject drawing #define GI_COMPATPOLY2 0x00000080 // so does HEXDD's MAP47 -#define GI_NOTEXTCOLOR 0x00000100 +#define GI_NOTEXTCOLOR 0x00000100 // Chex Quest 3 would have everything green +#define GI_COMPATPORTAL 0x00000200 // Urban Brawl relies on the old portal code #include "gametype.h" diff --git a/src/svnrevision.h b/src/svnrevision.h index 8a4e886a..4b01b57c 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3018" -#define ZD_SVN_REVISION_NUMBER 3018 +#define ZD_SVN_REVISION_STRING "3019" +#define ZD_SVN_REVISION_NUMBER 3019 From ca25e812dcb1cc7df7134d5a754aaf6067c9d995 Mon Sep 17 00:00:00 2001 From: gez Date: Fri, 3 Dec 2010 09:14:09 +0000 Subject: [PATCH 54/82] * Updated to ZDoom r3020: - Fixed what appears to be a copy/paste error in the CMakeLists.txt. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1120 b0f79afe-0144-0410-b225-9a4edf0717df --- src/CMakeLists.txt | 3 +-- src/svnrevision.h | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9141c922..8ef43a63 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -396,8 +396,7 @@ endif( SSE_MATTERS ) if( CMAKE_COMPILER_IS_GNUCXX ) if( PROFILE ) - set( CMAKE_C_FLinclude( FindFluidSynth.cmake ) -AGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" ) + set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" ) set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg" ) set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -pg" ) set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -pg" ) diff --git a/src/svnrevision.h b/src/svnrevision.h index 4b01b57c..cdf67fcc 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3019" -#define ZD_SVN_REVISION_NUMBER 3019 +#define ZD_SVN_REVISION_STRING "3020" +#define ZD_SVN_REVISION_NUMBER 3020 From db50bb9bc5b3751e2deaa6d82f98b9d2da1085fd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Dec 2010 08:56:09 +0000 Subject: [PATCH 55/82] ZDoom r3021: * expanded compat_trace flag to apply also to sight checks. * Set trace compatibility for Real World MAP11. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1121 b0f79afe-0144-0410-b225-9a4edf0717df --- src/p_sight.cpp | 5 +++++ wadsrc/static/compatibility.txt | 1 + 2 files changed, 6 insertions(+) diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 4324ebc0..359b5d4d 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -102,6 +102,11 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) // // crosses a two sided line // + + // ignore self referencing sectors if COMPAT_TRACE is on + if ((i_compatflags & COMPATF_TRACE) && li->frontsector == li->backsector) + return true; + fixed_t trX=trace.x + FixedMul (trace.dx, in->frac); fixed_t trY=trace.y + FixedMul (trace.dy, in->frac); P_LineOpening (open, NULL, li, trX, trY); diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index c3a4404a..14cda796 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -53,6 +53,7 @@ F84AB4557464A383E93F37CD3A82AC48 // MM2 map03 } 2FE901F659A16E58D7BCD7C30021C238 // AV map15 +74AF92E96FE10D039D31C1F6526D7D7C // Real World map11 { trace } From d5a12ecbe69e9841c5bf3898549a57ff9aeac133 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Dec 2010 10:00:38 +0000 Subject: [PATCH 56/82] - fixed: gl_FakeFlat must copy the light level when handling the back sector. Otherwise some fog boundary calculations will fail. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1122 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_fakeflat.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gl/scene/gl_fakeflat.cpp b/src/gl/scene/gl_fakeflat.cpp index 6f97993d..7f683ef8 100644 --- a/src/gl/scene/gl_fakeflat.cpp +++ b/src/gl/scene/gl_fakeflat.cpp @@ -242,8 +242,13 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac int diffTex = (sec->heightsec->MoreFlags & SECF_CLIPFAKEPLANES); sector_t * s = sec->heightsec; - - *dest=*sec; + +#if 0 + *dest=*sec; // This will invoke the copy operator which isn't really needed here. Memcpy is faster. +#else + memcpy(dest, sec, sizeof(sector_t)); +#endif + // Replace floor and ceiling height with control sector's heights. if (diffTex) { @@ -316,6 +321,10 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::vbo_fakefloor]; dest->vboheight[sector_t::ceiling] = s->vboheight[sector_t::floor]; + if (!(s->MoreFlags & SECF_NOFAKELIGHT)) + { + dest->lightlevel = s->lightlevel; + } if (!back) { @@ -341,7 +350,6 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac if (!(s->MoreFlags & SECF_NOFAKELIGHT)) { - dest->lightlevel = s->lightlevel; dest->SetPlaneLight(sector_t::floor, s->GetPlaneLight(sector_t::floor)); dest->SetPlaneLight(sector_t::ceiling, s->GetPlaneLight(sector_t::ceiling)); dest->ChangeFlags(sector_t::floor, -1, s->GetFlags(sector_t::floor)); @@ -364,6 +372,11 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::ceiling]; dest->vboheight[sector_t::ceiling] = sec->vboheight[sector_t::ceiling]; + if (!(s->MoreFlags & SECF_NOFAKELIGHT)) + { + dest->lightlevel = s->lightlevel; + } + if (!back) { dest->SetTexture(sector_t::ceiling, diffTex ? sec->GetTexture(sector_t::ceiling) : s->GetTexture(sector_t::ceiling), false); From 85719dc69cd101b2461d646d7097c120dae733e7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Dec 2010 16:16:46 +0000 Subject: [PATCH 57/82] - fixed: The intermission screen did not initialize its texture variable when the texture was invalid. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1123 b0f79afe-0144-0410-b225-9a4edf0717df --- src/intermission/intermission.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index f0d30857..1287f93c 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -110,12 +110,8 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) { texname = GStrings[texname+1]; } - FTextureID tex = TexMan.CheckForTexture(texname, FTexture::TEX_MiscPatch); - if (tex.isValid()) - { - mBackground = tex; - mFlatfill = desc->mFlatfill; - } + mBackground = TexMan.CheckForTexture(texname, FTexture::TEX_MiscPatch); + mFlatfill = desc->mFlatfill; S_Sound (CHAN_VOICE | CHAN_UI, desc->mSound, 1.0f, ATTN_NONE); if (desc->mPalette.IsNotEmpty() && (lumpnum = Wads.CheckNumForFullName(desc->mPalette, true)) > 0) { From 43d81f34c54f47729803a6b8f0f9172a3a8bf339 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Dec 2010 16:18:32 +0000 Subject: [PATCH 58/82] - Fixed: AActor::ClearCounters should not decrease the kill count if it is called for a dead monster which can happen in Thing_Remove. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1124 b0f79afe-0144-0410-b225-9a4edf0717df --- src/p_mobj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index adfbeb0e..a7360089 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5630,7 +5630,7 @@ const char *AActor::GetTag(const char *def) const void AActor::ClearCounters() { - if (CountsAsKill()) + if (CountsAsKill() && health > 0) { level.total_monsters--; flags &= ~MF_COUNTKILL; From cc7ac147675fd102102d964cd9bc75c75a14c958 Mon Sep 17 00:00:00 2001 From: gez Date: Fri, 10 Dec 2010 12:51:08 +0000 Subject: [PATCH 59/82] * Updated to ZDoom r3025: - Fixed: Portal setup did some incorrect validity checks. - Fixed: The 'secret' CCMD used FStrings directly as printf parameters. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1125 b0f79afe-0144-0410-b225-9a4edf0717df --- src/c_cmds.cpp | 4 ++-- src/p_spec.cpp | 4 ++-- src/svnrevision.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 12055ebc..0831c805 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -1030,10 +1030,10 @@ CCMD(secret) { FString levelname; level_info_t *info = FindLevelInfo(mapname); - levelname.Format("%s - %s\n", mapname, info->LevelName); + levelname.Format("%s - %s\n", mapname, info->LevelName.GetChars()); size_t llen = levelname.Len() - 1; for(size_t ii=0; iitid); sector_t *Sector = point->Sector; Sector->FloorSkyBox = static_cast(it.Next()); - if (Sector->FloorSkyBox != NULL || !Sector->FloorSkyBox->bAlways) + if (Sector->FloorSkyBox != NULL && Sector->FloorSkyBox->bAlways) { Sector->FloorSkyBox->Mate = point; if (Sector->GetAlpha(sector_t::floor) == OPAQUE) @@ -880,7 +880,7 @@ static void SetupCeilingPortal (AStackPoint *point) NActorIterator it (NAME_UpperStackLookOnly, point->tid); sector_t *Sector = point->Sector; Sector->CeilingSkyBox = static_cast(it.Next()); - if (Sector->CeilingSkyBox != NULL || !Sector->CeilingSkyBox->bAlways) + if (Sector->CeilingSkyBox != NULL && Sector->CeilingSkyBox->bAlways) { Sector->CeilingSkyBox->Mate = point; if (Sector->GetAlpha(sector_t::ceiling) == OPAQUE) diff --git a/src/svnrevision.h b/src/svnrevision.h index cdf67fcc..961f7074 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3020" -#define ZD_SVN_REVISION_NUMBER 3020 +#define ZD_SVN_REVISION_STRING "3025" +#define ZD_SVN_REVISION_NUMBER 3025 From d444a0a4b023220bfceaf79a7b10acfe94625ce3 Mon Sep 17 00:00:00 2001 From: gez Date: Sat, 11 Dec 2010 19:47:05 +0000 Subject: [PATCH 60/82] * Updated to ZDoom r3026: - Moved texture counting code into FTextureManager. - Moved all code and data for Build tile management into FTextureManager. - Moved texture animation management into FTextureManager. - Changed: Animate textures only once per frame, not per view. Otherwise with animations that have sub-frame accuracy camera textures of the same area can show different animation frames if the frame changes falls between the rendering of the different views. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1126 b0f79afe-0144-0410-b225-9a4edf0717df --- gzdoom.vcproj | 8 +- src/d_main.cpp | 9 +- src/p_setup.cpp | 1 - src/r_data.cpp | 98 ---- src/r_local.h | 6 - src/r_main.cpp | 1 - src/r_main.h | 1 - src/r_sky.cpp | 17 + src/r_sky.h | 1 + src/svnrevision.h | 4 +- src/{r_anim.cpp => textures/animations.cpp} | 521 +++++++++----------- src/textures/buildtexture.cpp | 29 +- src/textures/texturemanager.cpp | 144 +++++- src/textures/textures.h | 80 ++- 14 files changed, 484 insertions(+), 436 deletions(-) rename src/{r_anim.cpp => textures/animations.cpp} (64%) diff --git a/gzdoom.vcproj b/gzdoom.vcproj index bea97557..cf19ba69 100644 --- a/gzdoom.vcproj +++ b/gzdoom.vcproj @@ -2304,10 +2304,6 @@ - - @@ -2428,6 +2424,10 @@ + + diff --git a/src/d_main.cpp b/src/d_main.cpp index 61400d8a..fd03a5c4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -712,10 +712,12 @@ void D_Display () } else { + unsigned int nowtime = I_FPSTime(); + TexMan.UpdateAnimations(nowtime); + R_UpdateSky(nowtime); switch (gamestate) { case GS_FULLCONSOLE: - R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); C_DrawConsole (false); @@ -780,7 +782,6 @@ void D_Display () break; case GS_INTERMISSION: - R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); WI_Drawer (); @@ -788,7 +789,6 @@ void D_Display () break; case GS_FINALE: - R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); F_Drawer (); @@ -796,7 +796,6 @@ void D_Display () break; case GS_DEMOSCREEN: - R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); D_PageDrawer (); @@ -1987,7 +1986,7 @@ void D_DoomMain (void) S_Init (); Printf ("ST_Init: Init startup screen.\n"); - StartScreen = FStartupScreen::CreateInstance (R_GuesstimateNumTextures() + 5); + StartScreen = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5); ParseCompatibility(); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index bb274bbc..89acb2db 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4125,7 +4125,6 @@ void P_Init () atterm (P_Shutdown); P_InitEffects (); // [RH] - R_InitPicAnims (); P_InitSwitchList (); P_InitTerrainTypes (); P_InitKeyMessages (); diff --git a/src/r_data.cpp b/src/r_data.cpp index ee40e29c..37602007 100644 --- a/src/r_data.cpp +++ b/src/r_data.cpp @@ -286,103 +286,6 @@ void R_InitData () StartScreen->Progress(); } -//=========================================================================== -// -// R_GuesstimateNumTextures -// -// Returns an estimate of the number of textures R_InitData will have to -// process. Used by D_DoomMain() when it calls ST_Init(). -// -//=========================================================================== - -int R_GuesstimateNumTextures () -{ - int numtex = 0; - - for(int i = Wads.GetNumLumps()-1; i>=0; i--) - { - int space = Wads.GetLumpNamespace(i); - switch(space) - { - case ns_flats: - case ns_sprites: - case ns_newtextures: - case ns_hires: - case ns_patches: - case ns_graphics: - numtex++; - break; - - default: - if (Wads.GetLumpFlags(i) & LUMPF_MAYBEFLAT) numtex++; - - break; - } - } - - numtex += R_CountBuildTiles (); - numtex += R_CountTexturesX (); - return numtex; -} - -//=========================================================================== -// -// R_CountTexturesX -// -// See R_InitTextures() for the logic in deciding what lumps to check. -// -//=========================================================================== - -static int R_CountTexturesX () -{ - int count = 0; - int wadcount = Wads.GetNumWads(); - for (int wadnum = 0; wadnum < wadcount; wadnum++) - { - // Use the most recent PNAMES for this WAD. - // Multiple PNAMES in a WAD will be ignored. - int pnames = Wads.CheckNumForName("PNAMES", ns_global, wadnum, false); - - // should never happen except for zdoom.pk3 - if (pnames < 0) continue; - - // Only count the patches if the PNAMES come from the current file - // Otherwise they have already been counted. - if (Wads.GetLumpFile(pnames) == wadnum) - { - count += R_CountLumpTextures (pnames); - } - - int texlump1 = Wads.CheckNumForName ("TEXTURE1", ns_global, wadnum); - int texlump2 = Wads.CheckNumForName ("TEXTURE2", ns_global, wadnum); - - count += R_CountLumpTextures (texlump1) - 1; - count += R_CountLumpTextures (texlump2) - 1; - } - return count; -} - -//=========================================================================== -// -// R_CountLumpTextures -// -// Returns the number of patches in a PNAMES/TEXTURE1/TEXTURE2 lump. -// -//=========================================================================== - -static int R_CountLumpTextures (int lumpnum) -{ - if (lumpnum >= 0) - { - FWadLump file = Wads.OpenLumpNum (lumpnum); - DWORD numtex; - - file >> numtex; - return numtex >= 0 ? numtex : 0; - } - return 0; -} - //=========================================================================== // // R_DeinitData @@ -392,7 +295,6 @@ static int R_CountLumpTextures (int lumpnum) void R_DeinitData () { R_DeinitColormaps (); - R_DeinitBuildTiles(); FCanvasTextureInfo::EmptyList(); // Free openings diff --git a/src/r_local.h b/src/r_local.h index b4508a22..c666b1de 100644 --- a/src/r_local.h +++ b/src/r_local.h @@ -39,12 +39,6 @@ #include "r_things.h" #include "r_draw.h" -// r_anim.cpp - -void R_InitPicAnims (); -void R_AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD animspeed /* in ms */, DWORD speedrange=0); -void R_UpdateAnimations (DWORD mstime); - bool R_AlignFlat (int linenum, int side, int fc); #endif // __R_LOCAL_H__ diff --git a/src/r_main.cpp b/src/r_main.cpp index 435f7a41..3df22bd8 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1089,7 +1089,6 @@ void R_SetupFrame (AActor *actor) iview->otic = nowtic; } - R_UpdateAnimations (I_FPSTime()); r_TicFrac = I_GetTimeFrac (&r_FrameTime); if (cl_capfps || r_NoInterpolate) { diff --git a/src/r_main.h b/src/r_main.h index e633404e..c894a2bc 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -189,7 +189,6 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, int x, int y, int wid void R_ResetViewInterpolation (); // Called by startup code. -int R_GuesstimateNumTextures (); void R_Init (void); void R_ExecuteSetViewSize (void); diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 544c1ded..e9c319de 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -137,3 +137,20 @@ void R_InitSkyMap () sky2cyl = MAX(skytex2->GetWidth(), skytex2->xScale >> (16 - 10)); } + +//========================================================================== +// +// R_UpdateSky +// +// Performs sky scrolling +// +//========================================================================== + +void R_UpdateSky (DWORD mstime) +{ + // Scroll the sky + double ms = (double)mstime * FRACUNIT; + sky1pos = ms * level.skyspeed1; + sky2pos = ms * level.skyspeed2; +} + diff --git a/src/r_sky.h b/src/r_sky.h index 3e836ec3..f285c426 100644 --- a/src/r_sky.h +++ b/src/r_sky.h @@ -38,5 +38,6 @@ extern bool skystretch; // Called whenever the sky changes. void R_InitSkyMap (); +void R_UpdateSky (DWORD mstime); #endif //__R_SKY_H__ diff --git a/src/svnrevision.h b/src/svnrevision.h index 961f7074..ed7398b5 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3025" -#define ZD_SVN_REVISION_NUMBER 3025 +#define ZD_SVN_REVISION_STRING "3026" +#define ZD_SVN_REVISION_NUMBER 3026 diff --git a/src/r_anim.cpp b/src/textures/animations.cpp similarity index 64% rename from src/r_anim.cpp rename to src/textures/animations.cpp index cac36186..a4f0efe0 100644 --- a/src/r_anim.cpp +++ b/src/textures/animations.cpp @@ -49,69 +49,91 @@ // TYPES ------------------------------------------------------------------- -// -// Animating textures and planes -// -// [RH] Expanded to work with a Hexen ANIMDEFS lump -// - -struct FAnimDef -{ - FTextureID BasePic; - WORD NumFrames; - WORD CurFrame; - BYTE AnimType; - DWORD SwitchTime; // Time to advance to next frame - struct FAnimFrame - { - DWORD SpeedMin; // Speeds are in ms, not tics - DWORD SpeedRange; - FTextureID FramePic; - } Frames[1]; - enum - { - ANIM_Forward, - ANIM_Backward, - ANIM_OscillateUp, - ANIM_OscillateDown, - ANIM_DiscreteFrames - }; - - void SetSwitchTime (DWORD mstime); -}; - -// This is an array of pointers to animation definitions. -// When it is destroyed, it deletes any animations it points to as well. -class AnimArray : public TArray -{ -public: - ~AnimArray(); - void AddAnim (FAnimDef *anim); - void FixAnimations (); -}; - // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void R_InitAnimDefs (); -static void R_AddComplexAnim (FTextureID picnum, const TArray &frames); -static void ParseAnim (FScanner &sc, bool istex); -static void ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing); -static void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray &frames); -static FTextureID ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetype, bool allowMissing); -static void ParseTime (FScanner &sc, DWORD &min, DWORD &max); - // PUBLIC DATA DEFINITIONS ------------------------------------------------- // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static AnimArray Anims; static FRandom pr_animatepictures ("AnimatePics"); // CODE -------------------------------------------------------------------- //========================================================================== // -// R_InitPicAnims +// FTextureManager :: AddAnim +// +// Adds a new animation to the array. If one with the same basepic as the +// new one already exists, it is replaced. +// +//========================================================================== + +void FTextureManager::AddAnim (FAnimDef *anim) +{ + // Search for existing duplicate. + for (unsigned int i = 0; i < mAnimations.Size(); ++i) + { + if (mAnimations[i]->BasePic == anim->BasePic) + { + // Found one! + free (mAnimations[i]); + mAnimations[i] = anim; + return; + } + } + // Didn't find one, so add it at the end. + mAnimations.Push (anim); +} + +//========================================================================== +// +// FTextureManager :: AddSimpleAnim +// +// Creates an animation with simple characteristics. This is used for +// original Doom (non-ANIMDEFS-style) animations and Build animations. +// +//========================================================================== + +void FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange) +{ + if (AreTexturesCompatible(picnum, picnum + (animcount - 1))) + { + FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef)); + anim->CurFrame = 0; + anim->BasePic = picnum; + anim->NumFrames = animcount; + anim->AnimType = animtype; + anim->SwitchTime = 0; + anim->Frames[0].SpeedMin = speedmin; + anim->Frames[0].SpeedRange = speedrange; + anim->Frames[0].FramePic = anim->BasePic; + AddAnim (anim); + } +} + +//========================================================================== +// +// FTextureManager :: AddComplexAnim +// +// Creates an animation with individually defined frames. +// +//========================================================================== + +void FTextureManager::AddComplexAnim (FTextureID picnum, const TArray &frames) +{ + FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0])); + anim->BasePic = picnum; + anim->NumFrames = frames.Size(); + anim->CurFrame = 0; + anim->AnimType = FAnimDef::ANIM_DiscreteFrames; + anim->SwitchTime = 0; + memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[0])); + AddAnim (anim); +} + +//========================================================================== +// +// FTextureManager :: Initanimated // // [description copied from BOOM] // Load the table of animation definitions, checking for existence of @@ -139,9 +161,9 @@ static FRandom pr_animatepictures ("AnimatePics"); CVAR(Bool, debuganimated, false, 0) -void R_InitPicAnims (void) +void FTextureManager::InitAnimated (void) { - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable; + const BITFIELD texflags = TEXMAN_Overridable; // I think better not! This is only for old ANIMATED definition that // don't know about ZDoom's more flexible texture system. // | FTextureManager::TEXMAN_TryAny; @@ -163,17 +185,17 @@ void R_InitPicAnims (void) if (*anim_p /* .istexture */ & 1) { // different episode ? - if (!(pic1 = TexMan.CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Wall, texflags)).Exists() || - !(pic2 = TexMan.CheckForTexture (anim_p + 1 /* .endname */, FTexture::TEX_Wall, texflags)).Exists()) + if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Wall, texflags)).Exists() || + !(pic2 = CheckForTexture (anim_p + 1 /* .endname */, FTexture::TEX_Wall, texflags)).Exists()) continue; // [RH] Bit 1 set means allow decals on walls with this texture - TexMan[pic2]->bNoDecals = TexMan[pic1]->bNoDecals = !(*anim_p & 2); + Texture(pic2)->bNoDecals = Texture(pic1)->bNoDecals = !(*anim_p & 2); } else { - if (!(pic1 = TexMan.CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Flat, texflags)).Exists() || - !(pic2 = TexMan.CheckForTexture (anim_p + 1 /* .startname */, FTexture::TEX_Flat, texflags)).Exists()) + if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Flat, texflags)).Exists() || + !(pic2 = CheckForTexture (anim_p + 1 /* .startname */, FTexture::TEX_Flat, texflags)).Exists()) continue; } if (pic1 == pic2) @@ -183,8 +205,8 @@ void R_InitPicAnims (void) continue; } - FTexture *tex1 = TexMan[pic1]; - FTexture *tex2 = TexMan[pic2]; + FTexture *tex1 = Texture(pic1); + FTexture *tex2 = Texture(pic2); if (tex1->UseType != tex2->UseType) { @@ -213,71 +235,22 @@ void R_InitPicAnims (void) (BYTE(anim_p[21]) << 16) | (BYTE(anim_p[22]) << 24), 1000, 35); - R_AddSimpleAnim (pic1, pic2 - pic1 + 1, animtype, animspeed); + AddSimpleAnim (pic1, pic2 - pic1 + 1, animtype, animspeed); } } - // [RH] Load any ANIMDEFS lumps - R_InitAnimDefs (); - Anims.FixAnimations (); } //========================================================================== // -// R_AddSimpleAnim -// -// Creates an animation with simple characteristics. This is used for -// original Doom (non-ANIMDEFS-style) animations and Build animations. -// -//========================================================================== - -void R_AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange) -{ - if (TexMan.AreTexturesCompatible(picnum, picnum + (animcount - 1))) - { - FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef)); - anim->CurFrame = 0; - anim->BasePic = picnum; - anim->NumFrames = animcount; - anim->AnimType = animtype; - anim->SwitchTime = 0; - anim->Frames[0].SpeedMin = speedmin; - anim->Frames[0].SpeedRange = speedrange; - anim->Frames[0].FramePic = anim->BasePic; - Anims.AddAnim (anim); - } -} - -//========================================================================== -// -// R_AddComplexAnim -// -// Creates an animation with individually defined frames. -// -//========================================================================== - -static void R_AddComplexAnim (FTextureID picnum, const TArray &frames) -{ - FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0])); - anim->BasePic = picnum; - anim->NumFrames = frames.Size(); - anim->CurFrame = 0; - anim->AnimType = FAnimDef::ANIM_DiscreteFrames; - anim->SwitchTime = 0; - memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[0])); - Anims.AddAnim (anim); -} - -//========================================================================== -// -// R_InitAnimDefs +// FTextureManager :: InitAnimDefs // // This uses a Hexen ANIMDEFS lump to define the animation sequences // //========================================================================== -static void R_InitAnimDefs () +void FTextureManager::InitAnimDefs () { - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; int lump, lastlump = 0; while ((lump = Wads.FindLump ("ANIMDEFS", &lastlump)) != -1) @@ -288,11 +261,11 @@ static void R_InitAnimDefs () { if (sc.Compare ("flat")) { - ParseAnim (sc, false); + ParseAnim (sc, FTexture::TEX_Flat); } else if (sc.Compare ("texture")) { - ParseAnim (sc, true); + ParseAnim (sc, FTexture::TEX_Wall); } else if (sc.Compare ("switch")) { @@ -301,105 +274,11 @@ static void R_InitAnimDefs () // [GRB] Added warping type 2 else if (sc.Compare ("warp") || sc.Compare ("warp2")) { - bool isflat = false; - bool type2 = sc.Compare ("warp2"); // [GRB] - sc.MustGetString (); - if (sc.Compare ("flat")) - { - isflat = true; - sc.MustGetString (); - } - else if (sc.Compare ("texture")) - { - isflat = false; - sc.MustGetString (); - } - else - { - sc.ScriptError (NULL); - } - FTextureID picnum = TexMan.CheckForTexture (sc.String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags); - if (picnum.isValid()) - { - FTexture * warper = TexMan[picnum]; - - // don't warp a texture more than once - if (!warper->bWarped) - { - if (type2) // [GRB] - warper = new FWarp2Texture (warper); - else - warper = new FWarpTexture (warper); - TexMan.ReplaceTexture (picnum, warper, false); - } - - if (sc.CheckFloat()) - { - static_cast(warper)->SetSpeed(float(sc.Float)); - } - - // No decals on warping textures, by default. - // Warping information is taken from the last warp - // definition for this texture. - warper->bNoDecals = true; - if (sc.GetString ()) - { - if (sc.Compare ("allowdecals")) - { - warper->bNoDecals = false; - } - else - { - sc.UnGet (); - } - } - } + ParseWarp(sc); } else if (sc.Compare ("cameratexture")) { - int width, height; - int fitwidth, fitheight; - FString picname; - - sc.MustGetString (); - picname = sc.String; - sc.MustGetNumber (); - width = sc.Number; - sc.MustGetNumber (); - height = sc.Number; - FTextureID picnum = TexMan.CheckForTexture (picname, FTexture::TEX_Flat, texflags); - FTexture *viewer = new FCanvasTexture (picname, width, height); - if (picnum.Exists()) - { - FTexture *oldtex = TexMan[picnum]; - fitwidth = oldtex->GetScaledWidth (); - fitheight = oldtex->GetScaledHeight (); - viewer->UseType = oldtex->UseType; - TexMan.ReplaceTexture (picnum, viewer, true); - } - else - { - fitwidth = width; - fitheight = height; - // [GRB] No need for oldtex - viewer->UseType = FTexture::TEX_Wall; - TexMan.AddTexture (viewer); - } - if (sc.GetString()) - { - if (sc.Compare ("fit")) - { - sc.MustGetNumber (); - fitwidth = sc.Number; - sc.MustGetNumber (); - fitheight = sc.Number; - } - else - { - sc.UnGet (); - } - } - viewer->SetScaledSize(fitwidth, fitheight); + ParseCameraTexture(sc); } else if (sc.Compare ("animatedDoor")) { @@ -408,12 +287,11 @@ static void R_InitAnimDefs () else if (sc.Compare("skyoffset")) { sc.MustGetString (); - FTextureID picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); + FTextureID picnum = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); sc.MustGetNumber(); if (picnum.Exists()) { - FTexture *tex = TexMan[picnum]; - tex->SkyOffset = sc.Number; + Texture(picnum)->SkyOffset = sc.Number; } } else @@ -426,31 +304,28 @@ static void R_InitAnimDefs () //========================================================================== // -// ParseAnim +// FTextureManager :: ParseAnim // // Parse a single animation definition out of an ANIMDEFS lump and // create the corresponding animation structure. // //========================================================================== -static void ParseAnim (FScanner &sc, bool istex) +void FTextureManager::ParseAnim (FScanner &sc, int usetype) { - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; TArray frames (32); FTextureID picnum; - int usetype; int defined = 0; bool optional = false, missing = false; - usetype = istex ? FTexture::TEX_Wall : FTexture::TEX_Flat; - sc.MustGetString (); if (sc.Compare ("optional")) { optional = true; sc.MustGetString (); } - picnum = TexMan.CheckForTexture (sc.String, usetype, texflags); + picnum = CheckForTexture (sc.String, usetype, texflags); if (!picnum.Exists()) { @@ -467,7 +342,7 @@ static void ParseAnim (FScanner &sc, bool istex) // no decals on animating textures, by default if (picnum.isValid()) { - TexMan[picnum]->bNoDecals = true; + Texture(picnum)->bNoDecals = true; } while (sc.GetString ()) @@ -476,7 +351,7 @@ static void ParseAnim (FScanner &sc, bool istex) { if (picnum.isValid()) { - TexMan[picnum]->bNoDecals = false; + Texture(picnum)->bNoDecals = false; } continue; } @@ -517,20 +392,20 @@ static void ParseAnim (FScanner &sc, bool istex) { sc.ScriptError ("Animation needs at least 2 frames"); } - R_AddComplexAnim (picnum, frames); + AddComplexAnim (picnum, frames); } } //========================================================================== // -// ParseRangeAnim +// FTextureManager :: ParseRangeAnim // // Parse an animation defined using "range". Not that one range entry is // enough to define a complete animation, unlike "pic". // //========================================================================== -static void ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing) +void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing) { int type; FTextureID framenum; @@ -547,7 +422,7 @@ static void ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool m if (framenum < picnum) { type = FAnimDef::ANIM_Backward; - TexMan[framenum]->bNoDecals = TexMan[picnum]->bNoDecals; + Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals; swapvalues (framenum, picnum); } if (sc.GetString()) @@ -561,18 +436,18 @@ static void ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool m sc.UnGet (); } } - R_AddSimpleAnim (picnum, framenum - picnum + 1, type, min, max - min); + AddSimpleAnim (picnum, framenum - picnum + 1, type, min, max - min); } //========================================================================== // -// ParsePicAnim +// FTextureManager :: ParsePicAnim // // Parse a single frame from ANIMDEFS defined using "pic". // //========================================================================== -static void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray &frames) +void FTextureManager::ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray &frames) { FTextureID framenum; DWORD min, max; @@ -593,16 +468,16 @@ static void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool mis //========================================================================== // -// ParseFramenum +// FTextureManager :: ParseFramenum // // Reads a frame's texture from ANIMDEFS. It can either be an integral // offset from basepicnum or a specific texture name. // //========================================================================== -static FTextureID ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetype, bool allowMissing) +FTextureID FTextureManager::ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetype, bool allowMissing) { - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; FTextureID framenum; sc.MustGetString (); @@ -612,7 +487,7 @@ static FTextureID ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetyp } else { - framenum = TexMan.CheckForTexture (sc.String, usetype, texflags); + framenum = CheckForTexture (sc.String, usetype, texflags); if (!framenum.Exists() && !allowMissing) { sc.ScriptError ("Unknown texture %s", sc.String); @@ -623,13 +498,13 @@ static FTextureID ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetyp //========================================================================== // -// ParseTime +// FTextureManager :: ParseTime // // Reads a tics or rand time definition from ANIMDEFS. // //========================================================================== -static void ParseTime (FScanner &sc, DWORD &min, DWORD &max) +void FTextureManager::ParseTime (FScanner &sc, DWORD &min, DWORD &max) { sc.MustGetString (); if (sc.Compare ("tics")) @@ -652,53 +527,128 @@ static void ParseTime (FScanner &sc, DWORD &min, DWORD &max) //========================================================================== // -// AnimArray :: ~AnimArray +// FTextureManager :: ParseWarp // -// Frees all animations held in this array before freeing the array. +// Parses a warping texture definition // //========================================================================== -AnimArray::~AnimArray() +void FTextureManager::ParseWarp(FScanner &sc) { - for (unsigned i = 0; i < Size(); i++) + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + bool isflat = false; + bool type2 = sc.Compare ("warp2"); // [GRB] + sc.MustGetString (); + if (sc.Compare ("flat")) { - if ((*this)[i] != NULL) + isflat = true; + sc.MustGetString (); + } + else if (sc.Compare ("texture")) + { + isflat = false; + sc.MustGetString (); + } + else + { + sc.ScriptError (NULL); + } + FTextureID picnum = CheckForTexture (sc.String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags); + if (picnum.isValid()) + { + FTexture *warper = Texture(picnum); + + // don't warp a texture more than once + if (!warper->bWarped) { - M_Free ((*this)[i]); - (*this)[i] = NULL; + if (type2) warper = new FWarp2Texture (warper); + else warper = new FWarpTexture (warper); + + ReplaceTexture (picnum, warper, false); + } + + if (sc.CheckFloat()) + { + static_cast(warper)->SetSpeed(float(sc.Float)); + } + + // No decals on warping textures, by default. + // Warping information is taken from the last warp + // definition for this texture. + warper->bNoDecals = true; + if (sc.GetString ()) + { + if (sc.Compare ("allowdecals")) + { + warper->bNoDecals = false; + } + else + { + sc.UnGet (); + } } } } //========================================================================== // -// AnimArray :: AddAnim +// ParseCameraTexture // -// Adds a new animation to the array. If one with the same basepic as the -// new one already exists, it is replaced. +// Parses a camera texture definition // //========================================================================== -void AnimArray::AddAnim (FAnimDef *anim) +void FTextureManager::ParseCameraTexture(FScanner &sc) { - // Search for existing duplicate. - for (unsigned int i = 0; i < Anims.Size(); ++i) + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + int width, height; + int fitwidth, fitheight; + FString picname; + + sc.MustGetString (); + picname = sc.String; + sc.MustGetNumber (); + width = sc.Number; + sc.MustGetNumber (); + height = sc.Number; + FTextureID picnum = CheckForTexture (picname, FTexture::TEX_Flat, texflags); + FTexture *viewer = new FCanvasTexture (picname, width, height); + if (picnum.Exists()) { - if ((*this)[i]->BasePic == anim->BasePic) + FTexture *oldtex = Texture(picnum); + fitwidth = oldtex->GetScaledWidth (); + fitheight = oldtex->GetScaledHeight (); + viewer->UseType = oldtex->UseType; + ReplaceTexture (picnum, viewer, true); + } + else + { + fitwidth = width; + fitheight = height; + // [GRB] No need for oldtex + viewer->UseType = FTexture::TEX_Wall; + AddTexture (viewer); + } + if (sc.GetString()) + { + if (sc.Compare ("fit")) { - // Found one! - free ((*this)[i]); - (*this)[i] = anim; - return; + sc.MustGetNumber (); + fitwidth = sc.Number; + sc.MustGetNumber (); + fitheight = sc.Number; + } + else + { + sc.UnGet (); } } - // Didn't find one, so add it at the end. - Push (anim); + viewer->SetScaledSize(fitwidth, fitheight); } //========================================================================== // -// AnimArray :: FixAnimations +// FTextureManager :: FixAnimations // // Copy the "front sky" flag from an animated texture to the rest // of the textures in the animation, and make every texture in an @@ -706,21 +656,21 @@ void AnimArray::AddAnim (FAnimDef *anim) // //========================================================================== -void AnimArray::FixAnimations () +void FTextureManager::FixAnimations () { unsigned int i; int j; - for (i = 0; i < Size(); ++i) + for (i = 0; i < mAnimations.Size(); ++i) { - FAnimDef *anim = operator[] (i); + FAnimDef *anim = mAnimations[i]; if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames) { - if (TexMan[anim->BasePic]->bNoRemap0) + if (Texture(anim->BasePic)->bNoRemap0) { for (j = 0; j < anim->NumFrames; ++j) { - TexMan[anim->Frames[j].FramePic]->SetFrontSkyLayer (); + Texture(anim->Frames[j].FramePic)->SetFrontSkyLayer (); } } } @@ -730,11 +680,11 @@ void AnimArray::FixAnimations () bool noremap = false; const char *name; - name = TexMan[anim->BasePic]->Name; - nodecals = TexMan[anim->BasePic]->bNoDecals; + name = Texture(anim->BasePic)->Name; + nodecals = Texture(anim->BasePic)->bNoDecals; for (j = 0; j < anim->NumFrames; ++j) { - FTexture *tex = TexMan[anim->BasePic + j]; + FTexture *tex = Texture(anim->BasePic + j); noremap |= tex->bNoRemap0; tex->bNoDecals = nodecals; } @@ -742,7 +692,7 @@ void AnimArray::FixAnimations () { for (j = 0; j < anim->NumFrames; ++j) { - TexMan[anim->BasePic + j]->SetFrontSkyLayer (); + Texture(anim->BasePic + j)->SetFrontSkyLayer (); } } } @@ -768,19 +718,41 @@ void FAnimDef::SetSwitchTime (DWORD mstime) } } + //========================================================================== // -// R_UpdateAnimations +// FTextureManager :: SetTranslation +// +// Sets animation translation for a texture +// +//========================================================================== + +void FTextureManager::SetTranslation (FTextureID fromtexnum, FTextureID totexnum) +{ + if ((size_t)fromtexnum.texnum < Translation.Size()) + { + if ((size_t)totexnum.texnum >= Textures.Size()) + { + totexnum.texnum = fromtexnum.texnum; + } + Translation[fromtexnum.texnum] = totexnum.texnum; + } +} + + +//========================================================================== +// +// FTextureManager :: UpdateAnimations // // Updates texture translations for each animation and scrolls the skies. // //========================================================================== -void R_UpdateAnimations (DWORD mstime) +void FTextureManager::UpdateAnimations (DWORD mstime) { - for (unsigned int j = 0; j < Anims.Size(); ++j) + for (unsigned int j = 0; j < mAnimations.Size(); ++j) { - FAnimDef *anim = Anims[j]; + FAnimDef *anim = mAnimations[j]; // If this is the first time through R_UpdateAnimations, just // initialize the anim's switch time without actually animating. @@ -832,19 +804,14 @@ void R_UpdateAnimations (DWORD mstime) if (anim->AnimType == FAnimDef::ANIM_DiscreteFrames) { - TexMan.SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic); + SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic); } else { for (unsigned int i = 0; i < anim->NumFrames; i++) { - TexMan.SetTranslation (anim->BasePic + i, anim->BasePic + (i + anim->CurFrame) % anim->NumFrames); + SetTranslation (anim->BasePic + i, anim->BasePic + (i + anim->CurFrame) % anim->NumFrames); } } } - - // Scroll the sky - double ms = (double)mstime * FRACUNIT; - sky1pos = ms * level.skyspeed1; - sky2pos = ms * level.skyspeed2; } diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index 5f4172a6..2a3d1809 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -41,8 +41,6 @@ #include "cmdlib.h" #include "st_start.h" -static TArray BuildTileFiles; - //========================================================================== // // A texture defined in a Build TILESxxx.ART file @@ -158,7 +156,7 @@ const BYTE *FBuildTexture::GetColumn (unsigned int column, const Span **spans_ou // //=========================================================================== -void AddTiles (void *tiles) +void FTextureManager::AddTiles (void *tiles) { // int numtiles = LittleLong(((DWORD *)tiles)[1]); // This value is not reliable int tilestart = LittleLong(((DWORD *)tiles)[2]); @@ -183,7 +181,7 @@ void AddTiles (void *tiles) if (width <= 0 || height <= 0) continue; tex = new FBuildTexture (i, tiledata, width, height, xoffs, yoffs); - texnum = TexMan.AddTexture (tex); + texnum = AddTexture (tex); while (size > 0) { *tiledata = 255 - *tiledata; @@ -207,7 +205,7 @@ void AddTiles (void *tiles) speed = (anm >> 24) & 15; speed = MAX (1, (1 << speed) * 1000 / 120); // Convert from 120 Hz to 1000 Hz. - R_AddSimpleAnim (texnum, picanm[pic] & 63, type, speed); + AddSimpleAnim (texnum, picanm[pic] & 63, type, speed); } // Blood's rotation types: @@ -262,7 +260,7 @@ void AddTiles (void *tiles) // //=========================================================================== -static int CountTiles (void *tiles) +int FTextureManager::CountTiles (void *tiles) { int version = LittleLong(*(DWORD *)tiles); if (version != 1) @@ -285,7 +283,7 @@ static int CountTiles (void *tiles) // //=========================================================================== -int R_CountBuildTiles () +int FTextureManager::CountBuildTiles () { int numartfiles = 0; char artfile[] = "tilesXXX.art"; @@ -373,25 +371,10 @@ int R_CountBuildTiles () // //=========================================================================== -void R_InitBuildTiles () +void FTextureManager::InitBuildTiles () { for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i) { AddTiles (BuildTileFiles[i]); } } - -//=========================================================================== -// -// R_DeinitBuildTiles -// -//=========================================================================== - -void R_DeinitBuildTiles () -{ - for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i) - { - delete[] BuildTileFiles[i]; - } - BuildTileFiles.Clear(); -} diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index e562923d..80690a03 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -62,8 +62,6 @@ FTextureManager TexMan; FTextureManager::FTextureManager () { memset (HashFirst, -1, sizeof(HashFirst)); - // Texture 0 is a dummy texture used to indicate "no texture" - AddTexture (new FDummyTexture); } @@ -74,11 +72,43 @@ FTextureManager::FTextureManager () //========================================================================== FTextureManager::~FTextureManager () +{ + DeleteAll(); +} + +//========================================================================== +// +// FTextureManager :: DeleteAll +// +//========================================================================== + +void FTextureManager::DeleteAll() { for (unsigned int i = 0; i < Textures.Size(); ++i) { delete Textures[i].Texture; } + Textures.Clear(); + Translation.Clear(); + FirstTextureForFile.Clear(); + memset (HashFirst, -1, sizeof(HashFirst)); + DefaultTexture.SetInvalid(); + + for (unsigned i = 0; i < mAnimations.Size(); i++) + { + if (mAnimations[i] != NULL) + { + M_Free (mAnimations[i]); + mAnimations[i] = NULL; + } + } + mAnimations.Clear(); + + for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i) + { + delete[] BuildTileFiles[i]; + } + BuildTileFiles.Clear(); } //========================================================================== @@ -896,8 +926,14 @@ void FTextureManager::SortTexturesByType(int start, int end) void FTextureManager::Init() { + DeleteAll(); + // Init Build Tile data if it hasn't been done already + if (BuildTileFiles.Size() == 0) CountBuildTiles (); FTexture::InitGrayMap(); + // Texture 0 is a dummy texture used to indicate "no texture" + AddTexture (new FDummyTexture); + int wadcnt = Wads.GetNumWads(); for(int i = 0; i< wadcnt; i++) { @@ -907,7 +943,7 @@ void FTextureManager::Init() // Add one marker so that the last WAD is easier to handle and treat // Build tiles as a completely separate block. FirstTextureForFile.Push(Textures.Size()); - R_InitBuildTiles (); + InitBuildTiles (); FirstTextureForFile.Push(Textures.Size()); DefaultTexture = CheckForTexture ("-NOFLAT-", FTexture::TEX_Override, 0); @@ -938,6 +974,10 @@ void FTextureManager::Init() } } } + + InitAnimated(); + InitAnimDefs(); + FixAnimations(); } //========================================================================== @@ -988,6 +1028,104 @@ int FTextureManager::ReadTexture (FArchive &arc) else return -1; } +//=========================================================================== +// +// R_GuesstimateNumTextures +// +// Returns an estimate of the number of textures R_InitData will have to +// process. Used by D_DoomMain() when it calls ST_Init(). +// +//=========================================================================== + +int FTextureManager::GuesstimateNumTextures () +{ + int numtex = 0; + + for(int i = Wads.GetNumLumps()-1; i>=0; i--) + { + int space = Wads.GetLumpNamespace(i); + switch(space) + { + case ns_flats: + case ns_sprites: + case ns_newtextures: + case ns_hires: + case ns_patches: + case ns_graphics: + numtex++; + break; + + default: + if (Wads.GetLumpFlags(i) & LUMPF_MAYBEFLAT) numtex++; + + break; + } + } + + numtex += CountBuildTiles (); + numtex += CountTexturesX (); + return numtex; +} + +//=========================================================================== +// +// R_CountTexturesX +// +// See R_InitTextures() for the logic in deciding what lumps to check. +// +//=========================================================================== + +int FTextureManager::CountTexturesX () +{ + int count = 0; + int wadcount = Wads.GetNumWads(); + for (int wadnum = 0; wadnum < wadcount; wadnum++) + { + // Use the most recent PNAMES for this WAD. + // Multiple PNAMES in a WAD will be ignored. + int pnames = Wads.CheckNumForName("PNAMES", ns_global, wadnum, false); + + // should never happen except for zdoom.pk3 + if (pnames < 0) continue; + + // Only count the patches if the PNAMES come from the current file + // Otherwise they have already been counted. + if (Wads.GetLumpFile(pnames) == wadnum) + { + count += CountLumpTextures (pnames); + } + + int texlump1 = Wads.CheckNumForName ("TEXTURE1", ns_global, wadnum); + int texlump2 = Wads.CheckNumForName ("TEXTURE2", ns_global, wadnum); + + count += CountLumpTextures (texlump1) - 1; + count += CountLumpTextures (texlump2) - 1; + } + return count; +} + +//=========================================================================== +// +// R_CountLumpTextures +// +// Returns the number of patches in a PNAMES/TEXTURE1/TEXTURE2 lump. +// +//=========================================================================== + +int FTextureManager::CountLumpTextures (int lumpnum) +{ + if (lumpnum >= 0) + { + FWadLump file = Wads.OpenLumpNum (lumpnum); + DWORD numtex; + + file >> numtex; + return numtex >= 0 ? numtex : 0; + } + return 0; +} + + //========================================================================== // // operator<< diff --git a/src/textures/textures.h b/src/textures/textures.h index 61838a80..2a65d1dd 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -64,8 +64,6 @@ protected: FTextureID(int num) { texnum = num; } private: int texnum; - - friend void AddTiles (void *tiles); }; class FNullTextureID : public FTextureID @@ -76,6 +74,37 @@ public: FArchive &operator<< (FArchive &arc, FTextureID &tex); +// +// Animating textures and planes +// +// [RH] Expanded to work with a Hexen ANIMDEFS lump +// + +struct FAnimDef +{ + FTextureID BasePic; + WORD NumFrames; + WORD CurFrame; + BYTE AnimType; + DWORD SwitchTime; // Time to advance to next frame + struct FAnimFrame + { + DWORD SpeedMin; // Speeds are in ms, not tics + DWORD SpeedRange; + FTextureID FramePic; + } Frames[1]; + enum + { + ANIM_Forward, + ANIM_Backward, + ANIM_OscillateUp, + ANIM_OscillateDown, + ANIM_DiscreteFrames + }; + + void SetSwitchTime (DWORD mstime); +}; + // Patches. // A patch holds one or more columns. @@ -361,18 +390,6 @@ public: return Textures[Translation[i]].Texture; } - void SetTranslation (FTextureID fromtexnum, FTextureID totexnum) - { - if ((size_t)fromtexnum.texnum < Translation.Size()) - { - if ((size_t)totexnum.texnum >= Textures.Size()) - { - totexnum.texnum = fromtexnum.texnum; - } - Translation[fromtexnum.texnum] = totexnum.texnum; - } - } - enum { TEXMAN_TryAny = 1, @@ -389,7 +406,6 @@ public: void AddTexturesLumps (int lump1, int lump2, int patcheslump); void AddGroup(int wadnum, int ns, int usetype); void AddPatches (int lumpnum); - void AddTiles (void *tileFile); void AddHiresTextures (int wadnum); void LoadTextureDefs(int wadnum, const char *lumpname); void ParseXTexture(FScanner &sc, int usetype); @@ -403,6 +419,7 @@ public: void LoadTextureX(int wadnum); void AddTexturesForWad(int wadnum); void Init(); + void DeleteAll(); // Replaces one texture with another. The new texture will be assigned // the same name, slot, and use type as the texture it is replacing. @@ -420,8 +437,38 @@ public: void WriteTexture (FArchive &arc, int picnum); int ReadTexture (FArchive &arc); + void UpdateAnimations (DWORD mstime); + int GuesstimateNumTextures (); private: + + // texture counting + int CountTexturesX (); + int CountLumpTextures (int lumpnum); + + // Build tiles + void AddTiles (void *tiles); + int CountTiles (void *tiles); + int CountBuildTiles (); + void InitBuildTiles (); + + // Animation stuff + void AddAnim (FAnimDef *anim); + void FixAnimations (); + void InitAnimated (); + void InitAnimDefs (); + void AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange=0); + void AddComplexAnim (FTextureID picnum, const TArray &frames); + void ParseAnim (FScanner &sc, int usetype); + void ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing); + void ParsePicAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing, TArray &frames); + void ParseWarp(FScanner &sc); + void ParseCameraTexture(FScanner &sc); + FTextureID ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetype, bool allowMissing); + void ParseTime (FScanner &sc, DWORD &min, DWORD &max); + FTexture *Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; } + void SetTranslation (FTextureID fromtexnum, FTextureID totexnum); + struct TextureHash { FTexture *Texture; @@ -433,6 +480,9 @@ private: int HashFirst[HASH_SIZE]; FTextureID DefaultTexture; TArray FirstTextureForFile; + + TArray mAnimations; + TArray BuildTileFiles; }; extern FTextureManager TexMan; From d0338ea7a07389c135cb8d9a65f263bd121a9b7e Mon Sep 17 00:00:00 2001 From: gez Date: Tue, 14 Dec 2010 21:32:41 +0000 Subject: [PATCH 61/82] * Updated to ZDoom r3029: - Fixed: "Show IWAD selection dialog" was only shown on Windows. - Moved animated door definitions into texture manager and split all associated code off p_doors.cpp - Fixed GCC compilation. - Moved switch definitions into texture manager and split all associated code off p_switches.cpp into its own file. * Note: This is the last revision backward compatible with saves from the latest official version. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1127 b0f79afe-0144-0410-b225-9a4edf0717df --- gzdoom.vcproj | 4 + src/CMakeLists.txt | 3 +- src/p_doors.cpp | 164 +++--------- src/p_setup.cpp | 1 - src/p_spec.h | 18 +- src/p_switch.cpp | 433 +++++--------------------------- src/svnrevision.h | 4 +- src/textures/anim_switches.cpp | 390 ++++++++++++++++++++++++++++ src/textures/animations.cpp | 92 ++++++- src/textures/texturemanager.cpp | 21 ++ src/textures/textures.h | 42 ++++ src/win32/zdoom.rc | 4 +- wadsrc/static/menudef.txt | 4 +- 13 files changed, 649 insertions(+), 531 deletions(-) create mode 100644 src/textures/anim_switches.cpp diff --git a/gzdoom.vcproj b/gzdoom.vcproj index cf19ba69..35c0995a 100644 --- a/gzdoom.vcproj +++ b/gzdoom.vcproj @@ -2424,6 +2424,10 @@ + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8ef43a63..0de9b94f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -725,7 +725,6 @@ add_executable( zdoom WIN32 p_xlat.cpp parsecontext.cpp po_man.cpp - r_anim.cpp r_bsp.cpp r_data.cpp r_draw.cpp @@ -909,6 +908,8 @@ add_executable( zdoom WIN32 sound/music_timidity_mididevice.cpp sound/music_win_mididevice.cpp sound/music_pseudo_mididevice.cpp + textures/animations.cpp + textures/anim_switches.cpp textures/automaptexture.cpp textures/bitmap.cpp textures/buildtexture.cpp diff --git a/src/p_doors.cpp b/src/p_doors.cpp index e82adbe4..7f385242 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -496,51 +496,12 @@ void P_SpawnDoorRaiseIn5Mins (sector_t *sec) new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0); } -// Strife's animated doors. Based on Doom's unused sliding doors, but significantly improved. - -class DeletingDoorArray : public TArray -{ -public: - ~DeletingDoorArray() - { - for(unsigned i=0;iTextureFrames != NULL) - { - delete [] ani->TextureFrames; - ani->TextureFrames = NULL; - } - } - } -}; - -DeletingDoorArray DoorAnimations; - // EV_SlidingDoor : slide a door horizontally // (animate midtexture, then set noblocking line) // -// -// Return index into "DoorAnimations" array for which door type to use -// -static int P_FindSlidingDoorType (FTextureID picnum) -{ - unsigned int i; - - for (i = 0; i < DoorAnimations.Size(); ++i) - { - if (picnum == DoorAnimations[i].BaseTexture) - return i; - } - - return -1; -} - bool DAnimatedDoor::StartClosing () { - FDoorAnimation &ani = DoorAnimations[m_WhichDoorIndex]; - // CAN DOOR CLOSE? if (m_Sector->touching_thinglist != NULL) { @@ -557,9 +518,9 @@ bool DAnimatedDoor::StartClosing () m_Line1->flags |= ML_BLOCKING; m_Line2->flags |= ML_BLOCKING; - if (ani.CloseSound != NAME_None) + if (m_DoorAnim->CloseSound != NAME_None) { - SN_StartSequence (m_Sector, CHAN_CEILING, ani.CloseSound, 1); + SN_StartSequence (m_Sector, CHAN_CEILING, m_DoorAnim->CloseSound, 1); } m_Status = Closing; @@ -569,7 +530,12 @@ bool DAnimatedDoor::StartClosing () void DAnimatedDoor::Tick () { - FDoorAnimation &ani = DoorAnimations[m_WhichDoorIndex]; + if (m_DoorAnim == NULL) + { + // can only happen when a bad savegame is loaded. + Destroy(); + return; + } switch (m_Status) { @@ -581,7 +547,7 @@ void DAnimatedDoor::Tick () case Opening: if (!m_Timer--) { - if (++m_Frame >= ani.NumTextureFrames) + if (++m_Frame >= m_DoorAnim->NumTextureFrames) { // IF DOOR IS DONE OPENING... m_Line1->flags &= ~ML_BLOCKING; @@ -602,10 +568,10 @@ void DAnimatedDoor::Tick () // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... m_Timer = m_Speed; - m_Line1->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line1->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + m_Line1->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); } } break; @@ -648,10 +614,10 @@ void DAnimatedDoor::Tick () // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... m_Timer = m_Speed; - m_Line1->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line1->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + m_Line1->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); } } break; @@ -673,7 +639,12 @@ void DAnimatedDoor::Serialize (FArchive &arc) { Super::Serialize (arc); - FTextureID basetex = DoorAnimations[m_WhichDoorIndex].BaseTexture; + FTextureID basetex; + + if (arc.IsStoring()) + { + basetex = m_DoorAnim->BaseTexture; + } arc << m_Line1 << m_Line2 << m_Frame @@ -694,15 +665,11 @@ void DAnimatedDoor::Serialize (FArchive &arc) if (arc.IsLoading()) { - m_WhichDoorIndex = P_FindSlidingDoorType (basetex); - if (m_WhichDoorIndex == -1) - { // Oh no! The door animation doesn't exist anymore! - m_WhichDoorIndex = 0; - } + m_DoorAnim = TexMan.FindAnimatedDoor (basetex); } } -DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) +DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim) : DMovingCeiling (sec) { fixed_t topdist; @@ -711,13 +678,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) // The DMovingCeiling constructor automatically sets up an interpolation for us. // Stop it, since the ceiling is moving instantly here. StopInterpolation(); - m_WhichDoorIndex = P_FindSlidingDoorType (line->sidedef[0]->GetTexture(side_t::top)); - if (m_WhichDoorIndex < 0) - { - Printf ("EV_SlidingDoor: Textures are not defined for sliding door!"); - m_Status = Dead; - return; - } + m_DoorAnim = anim; m_Line1 = line; m_Line2 = line; @@ -756,9 +717,9 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) m_Line2->flags |= ML_BLOCKING; m_BotDist = m_Sector->ceilingplane.d; MoveCeiling (2048*FRACUNIT, topdist, 1); - if (DoorAnimations[m_WhichDoorIndex].OpenSound != NAME_None) + if (m_DoorAnim->OpenSound != NAME_None) { - SN_StartSequence (m_Sector, CHAN_INTERIOR, DoorAnimations[m_WhichDoorIndex].OpenSound, 1); + SN_StartSequence (m_Sector, CHAN_INTERIOR, m_DoorAnim->OpenSound, 1); } } @@ -798,9 +759,10 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) } return false; } - if (P_FindSlidingDoorType (line->sidedef[0]->GetTexture(side_t::top)) >= 0) + FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top)); + if (anim != NULL) { - new DAnimatedDoor (sec, line, speed, delay); + new DAnimatedDoor (sec, line, speed, delay, anim); return true; } return false; @@ -821,10 +783,11 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) { continue; } - if (P_FindSlidingDoorType (line->sidedef[0]->GetTexture(side_t::top)) >= 0) + FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top)); + if (anim != NULL) { rtn = true; - new DAnimatedDoor (sec, line, speed, delay); + new DAnimatedDoor (sec, line, speed, delay, anim); break; } } @@ -832,62 +795,3 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) return rtn; } -void P_ParseAnimatedDoor(FScanner &sc) -{ - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; - FDoorAnimation anim; - TArray frames; - bool error = false; - FTextureID v; - - sc.MustGetString(); - anim.BaseTexture = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); - - if (!anim.BaseTexture.Exists()) - { - error = true; - } - - while (sc.GetString ()) - { - if (sc.Compare ("opensound")) - { - sc.MustGetString (); - anim.OpenSound = sc.String; - } - else if (sc.Compare ("closesound")) - { - sc.MustGetString (); - anim.CloseSound = sc.String; - } - else if (sc.Compare ("pic")) - { - sc.MustGetString (); - if (IsNum (sc.String)) - { - v = anim.BaseTexture + (atoi(sc.String) - 1); - } - else - { - v = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); - if (!v.Exists() && anim.BaseTexture.Exists() && !error) - { - sc.ScriptError ("Unknown texture %s", sc.String); - } - frames.Push (v); - } - } - else - { - sc.UnGet (); - break; - } - } - if (!error) - { - anim.TextureFrames = new FTextureID[frames.Size()]; - memcpy (anim.TextureFrames, &frames[0], sizeof(FTextureID) * frames.Size()); - anim.NumTextureFrames = frames.Size(); - DoorAnimations.Push (anim); - } -} diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 89acb2db..cb380784 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4125,7 +4125,6 @@ void P_Init () atterm (P_Shutdown); P_InitEffects (); // [RH] - P_InitSwitchList (); P_InitTerrainTypes (); P_InitKeyMessages (); R_InitSprites (); diff --git a/src/p_spec.h b/src/p_spec.h index 70b79ec0..21427626 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -396,9 +396,6 @@ void EV_StartLightFading (int tag, int value, int tics); bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest=NULL); bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno); -void P_InitSwitchList (); -void P_ProcessSwitchDef (FScanner &sc); - // // P_PLATS // @@ -598,23 +595,12 @@ inline FArchive &operator<< (FArchive &arc, DDoor::EVlDoor &type) return arc; } -struct FDoorAnimation -{ - FTextureID BaseTexture; - FTextureID *TextureFrames; - int NumTextureFrames; - FName OpenSound; - FName CloseSound; -}; - -void P_ParseAnimatedDoor (FScanner &sc); - class DAnimatedDoor : public DMovingCeiling { DECLARE_CLASS (DAnimatedDoor, DMovingCeiling) public: DAnimatedDoor (sector_t *sector); - DAnimatedDoor (sector_t *sector, line_t *line, int speed, int delay); + DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim); void Serialize (FArchive &arc); void Tick (); @@ -623,7 +609,7 @@ public: protected: line_t *m_Line1, *m_Line2; int m_Frame; - int m_WhichDoorIndex; + FDoorAnimation *m_DoorAnim; int m_Timer; fixed_t m_BotDist; int m_Status; diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 42363358..622fd639 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -46,12 +46,9 @@ #include "w_wad.h" #include "tarray.h" #include "cmdlib.h" -#include "sc_man.h" #include "gi.h" -#define MAX_FRAMES 128 - static FRandom pr_switchanim ("AnimSwitch"); class DActiveButton : public DThinker @@ -76,338 +73,14 @@ protected: bool AdvanceFrame (); }; -struct FSwitchDef -{ - FTextureID PreTexture; // texture to switch from - WORD PairIndex; // switch def to use to return to PreTexture - WORD NumFrames; // # of animation frames - FSoundID Sound; // sound to play at start of animation - bool QuestPanel; // Special texture for Strife mission - struct frame // Array of times followed by array of textures - { // actual length of each array is - DWORD Time; - FTextureID Texture; - } u[1]; -}; - -static int STACK_ARGS SortSwitchDefs (const void *a, const void *b); -static FSwitchDef *ParseSwitchDef (FScanner &sc, bool ignoreBad); -static WORD AddSwitchDef (FSwitchDef *def); - -// -// CHANGE THE TEXTURE OF A WALL SWITCH TO ITS OPPOSITE -// - -class DeletingSwitchArray : public TArray -{ -public: - ~DeletingSwitchArray() - { - for(unsigned i=0;iPreTexture = def2->u[0].Texture = TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags); - def2->PreTexture = def1->u[0].Texture = TexMan.CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags); - def1->Sound = def2->Sound = 0; - def1->NumFrames = def2->NumFrames = 1; - def1->u[0].Time = def2->u[0].Time = 0; - def2->PairIndex = AddSwitchDef (def1); - def1->PairIndex = AddSwitchDef (def2); - } - } - } - - SwitchList.ShrinkToFit (); - - // Sort SwitchList for quick searching - origMap = new FSwitchDef *[SwitchList.Size ()]; - for (i = 0; i < (int)SwitchList.Size (); i++) - { - origMap[i] = SwitchList[i]; - } - - qsort (&SwitchList[0], i, sizeof(FSwitchDef *), SortSwitchDefs); - - // Correct the PairIndex of each switch def, since the sorting broke them - for (i = (int)(SwitchList.Size () - 1); i >= 0; i--) - { - FSwitchDef *def = SwitchList[i]; - if (def->PairIndex != 65535) - { - for (j = (int)(SwitchList.Size () - 1); j >= 0; j--) - { - if (SwitchList[j] == origMap[def->PairIndex]) - { - def->PairIndex = (WORD)j; - break; - } - } - } - } - - delete[] origMap; -} - -static int STACK_ARGS SortSwitchDefs (const void *a, const void *b) -{ - return (*(FSwitchDef **)a)->PreTexture - (*(FSwitchDef **)b)->PreTexture; -} - -// Parse a switch block in ANIMDEFS and add the definitions to SwitchList -void P_ProcessSwitchDef (FScanner &sc) -{ - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; - FString picname; - FSwitchDef *def1, *def2; - FTextureID picnum; - int gametype; - bool quest = false; - - def1 = def2 = NULL; - sc.MustGetString (); - if (sc.Compare ("doom")) - { - gametype = GAME_DoomChex; - sc.CheckNumber(); // skip the gamemission filter - } - else if (sc.Compare ("heretic")) - { - gametype = GAME_Heretic; - } - else if (sc.Compare ("hexen")) - { - gametype = GAME_Hexen; - } - else if (sc.Compare ("strife")) - { - gametype = GAME_Strife; - } - else if (sc.Compare ("any")) - { - gametype = GAME_Any; - } - else - { - // There is no game specified; just treat as any - //max = 240; - gametype = GAME_Any; - sc.UnGet (); - } - - sc.MustGetString (); - picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); - picname = sc.String; - while (sc.GetString ()) - { - if (sc.Compare ("quest")) - { - quest = true; - } - else if (sc.Compare ("on")) - { - if (def1 != NULL) - { - sc.ScriptError ("Switch already has an on state"); - } - def1 = ParseSwitchDef (sc, !picnum.Exists()); - } - else if (sc.Compare ("off")) - { - if (def2 != NULL) - { - sc.ScriptError ("Switch already has an off state"); - } - def2 = ParseSwitchDef (sc, !picnum.Exists()); - } - else - { - sc.UnGet (); - break; - } - } - - if (def1 == NULL || !picnum.Exists() || - (gametype != GAME_Any && !(gametype & gameinfo.gametype))) - { - if (def2 != NULL) - { - M_Free (def2); - } - if (def1 != NULL) - { - M_Free (def1); - } - return; - } - - // If the switch did not have an off state, create one that just returns - // it to the original texture without doing anything interesting - if (def2 == NULL) - { - def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); - def2->Sound = def1->Sound; - def2->NumFrames = 1; - def2->u[0].Time = 0; - def2->u[0].Texture = picnum; - } - - def1->PreTexture = picnum; - def2->PreTexture = def1->u[def1->NumFrames-1].Texture; - if (def1->PreTexture == def2->PreTexture) - { - sc.ScriptError ("The on state for switch %s must end with a texture other than %s", picname.GetChars(), picname.GetChars()); - } - def2->PairIndex = AddSwitchDef (def1); - def1->PairIndex = AddSwitchDef (def2); - def1->QuestPanel = def2->QuestPanel = quest; -} - -FSwitchDef *ParseSwitchDef (FScanner &sc, bool ignoreBad) -{ - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; - FSwitchDef *def; - TArray frames; - FSwitchDef::frame thisframe; - FTextureID picnum; - bool bad; - FSoundID sound; - - bad = false; - - while (sc.GetString ()) - { - if (sc.Compare ("sound")) - { - if (sound != 0) - { - sc.ScriptError ("Switch state already has a sound"); - } - sc.MustGetString (); - sound = sc.String; - } - else if (sc.Compare ("pic")) - { - sc.MustGetString (); - picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); - if (!picnum.Exists() && !ignoreBad) - { - //Printf ("Unknown switch texture %s\n", sc.String); - bad = true; - } - thisframe.Texture = picnum; - sc.MustGetString (); - if (sc.Compare ("tics")) - { - sc.MustGetNumber (); - thisframe.Time = sc.Number & 65535; - } - else if (sc.Compare ("rand")) - { - int min, max; - - sc.MustGetNumber (); - min = sc.Number & 65535; - sc.MustGetNumber (); - max = sc.Number & 65535; - if (min > max) - { - swapvalues (min, max); - } - thisframe.Time = ((max - min + 1) << 16) | min; - } - else - { - thisframe.Time = 0; // Shush, GCC. - sc.ScriptError ("Must specify a duration for switch frame"); - } - frames.Push(thisframe); - } - else - { - sc.UnGet (); - break; - } - } - if (frames.Size() == 0) - { - sc.ScriptError ("Switch state needs at least one frame"); - } - if (bad) - { - return NULL; - } - - def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, u[0]) + frames.Size()*sizeof(frames[0])); - def->Sound = sound; - def->NumFrames = frames.Size(); - memcpy (&def->u[0], &frames[0], frames.Size() * sizeof(frames[0])); - def->PairIndex = 65535; - return def; -} - -static WORD AddSwitchDef (FSwitchDef *def) -{ - unsigned int i; - - for (i = SwitchList.Size (); i-- > 0; ) - { - if (SwitchList[i]->PreTexture == def->PreTexture) - { - free (SwitchList[i]); - SwitchList[i] = def; - return (WORD)i; - } - } - return (WORD)SwitchList.Push (def); -} +//========================================================================== // // Start a button counting down till it turns off. // [RH] Rewritten to remove MAXBUTTONS limit. // +//========================================================================== + static bool P_StartButton (side_t *side, int Where, int switchnum, fixed_t x, fixed_t y, bool useagain) { @@ -428,40 +101,14 @@ static bool P_StartButton (side_t *side, int Where, int switchnum, return true; } -static int TryFindSwitch (side_t *side, int Where) -{ - int mid, low, high; - - FTextureID texture = side->GetTexture(Where); - high = (int)(SwitchList.Size () - 1); - if (high >= 0) - { - low = 0; - do - { - mid = (high + low) / 2; - if (SwitchList[mid]->PreTexture == texture) - { - return mid; - } - else if (texture < SwitchList[mid]->PreTexture) - { - high = mid - 1; - } - else - { - low = mid + 1; - } - } while (low <= high); - } - return -1; -} - +//========================================================================== // // Checks whether a switch is reachable // This is optional because old maps can rely on being able to // use non-reachable switches. // +//========================================================================== + bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) { // Activated from an empty side -> always succeed @@ -521,15 +168,15 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) if (open.range <= 0) goto onesided; - if ((TryFindSwitch (side, side_t::top)) != -1) + if ((TexMan.FindSwitch (side->GetTexture(side_t::top))) != -1) { return (user->z + user->height >= open.top); } - else if ((TryFindSwitch (side, side_t::bottom)) != -1) + else if ((TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != -1) { return (user->z <= open.bottom); } - else if ((line->flags & (ML_3DMIDTEX)) || (TryFindSwitch (side, side_t::mid)) != -1) + else if ((line->flags & (ML_3DMIDTEX)) || (TexMan.FindSwitch (side->GetTexture(side_t::mid))) != -1) { // 3DMIDTEX lines will force a mid texture check if no switch is found on this line // to keep compatibility with Eternity's implementation. @@ -544,24 +191,29 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) } } +//========================================================================== // // Function that changes wall texture. // Tell it if switch is ok to use again (1=yes, it's a button). // +//========================================================================== + bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest) { int texture; - int i, sound; + int sound; + int i; + FSwitchDef *Switch; - if ((i = TryFindSwitch (side, side_t::top)) != -1) + if ((i = TexMan.FindSwitch (side->GetTexture(side_t::top))) != -1) { texture = side_t::top; } - else if ((i = TryFindSwitch (side, side_t::bottom)) != -1) + else if ((i = TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != -1) { texture = side_t::bottom; } - else if ((i = TryFindSwitch (side, side_t::mid)) != -1) + else if ((i = TexMan.FindSwitch (side->GetTexture(side_t::mid))) != -1) { texture = side_t::mid; } @@ -573,11 +225,12 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques } return false; } + Switch = TexMan.GetSwitch(i); // EXIT SWITCH? - if (SwitchList[i]->Sound != 0) + if (Switch->Sound != 0) { - sound = SwitchList[i]->Sound; + sound = Switch->Sound; } else { @@ -599,20 +252,32 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques pt[0] = line->v1->x + (line->dx >> 1); pt[1] = line->v1->y + (line->dy >> 1); - side->SetTexture(texture, SwitchList[i]->u[0].Texture); - if (useAgain || SwitchList[i]->NumFrames > 1) + side->SetTexture(texture, Switch->u[0].Texture); + if (useAgain || Switch->NumFrames > 1) + { playsound = P_StartButton (side, texture, i, pt[0], pt[1], !!useAgain); + } else + { playsound = true; + } if (playsound) + { S_Sound (pt[0], pt[1], 0, CHAN_VOICE|CHAN_LISTENERZ, sound, 1, ATTN_STATIC); + } if (quest != NULL) { - *quest = SwitchList[i]->QuestPanel; + *quest = Switch->QuestPanel; } return true; } +//========================================================================== +// +// Button thinker +// +//========================================================================== + IMPLEMENT_CLASS (DActiveButton) DActiveButton::DActiveButton () @@ -640,6 +305,12 @@ DActiveButton::DActiveButton (side_t *side, int Where, WORD switchnum, AdvanceFrame (); } +//========================================================================== +// +// +// +//========================================================================== + void DActiveButton::Serialize (FArchive &arc) { SDWORD sidenum; @@ -656,20 +327,26 @@ void DActiveButton::Serialize (FArchive &arc) } } +//========================================================================== +// +// +// +//========================================================================== + void DActiveButton::Tick () { if (--m_Timer == 0) { - FSwitchDef *def = SwitchList[m_SwitchDef]; + FSwitchDef *def = TexMan.GetSwitch(m_SwitchDef); if (m_Frame == def->NumFrames - 1) { m_SwitchDef = def->PairIndex; if (m_SwitchDef != 65535) { - def = SwitchList[def->PairIndex]; + def = TexMan.GetSwitch(def->PairIndex); m_Frame = 65535; S_Sound (m_X, m_Y, 0, CHAN_VOICE|CHAN_LISTENERZ, - def->Sound != 0 ? def->Sound : FSoundID("switches/normbutn"), + def->Sound != 0 ? FSoundID(def->Sound) : FSoundID("switches/normbutn"), 1, ATTN_STATIC); bFlippable = false; } @@ -690,10 +367,16 @@ void DActiveButton::Tick () } } +//========================================================================== +// +// +// +//========================================================================== + bool DActiveButton::AdvanceFrame () { bool ret = false; - FSwitchDef *def = SwitchList[m_SwitchDef]; + FSwitchDef *def = TexMan.GetSwitch(m_SwitchDef); if (++m_Frame == def->NumFrames - 1) { diff --git a/src/svnrevision.h b/src/svnrevision.h index ed7398b5..cb1b930b 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3026" -#define ZD_SVN_REVISION_NUMBER 3026 +#define ZD_SVN_REVISION_STRING "3029" +#define ZD_SVN_REVISION_NUMBER 3029 diff --git a/src/textures/anim_switches.cpp b/src/textures/anim_switches.cpp new file mode 100644 index 00000000..cb1b5ae8 --- /dev/null +++ b/src/textures/anim_switches.cpp @@ -0,0 +1,390 @@ +/* +** p_switch.cpp +** Switch and button maintenance and animation +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** 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 "templates.h" +#include "textures/textures.h" +#include "doomdef.h" +#include "g_game.h" +#include "s_sound.h" +#include "doomstat.h" +#include "r_state.h" +#include "w_wad.h" +#include "cmdlib.h" +#include "sc_man.h" +#include "gi.h" + +static int STACK_ARGS SortSwitchDefs (const void *a, const void *b) +{ + return (*(FSwitchDef **)a)->PreTexture - (*(FSwitchDef **)b)->PreTexture; +} + +//========================================================================== +// +// P_InitSwitchList +// Only called at game initialization. +// +// [RH] Rewritten to use a BOOM-style SWITCHES lump and remove the +// MAXSWITCHES limit. +// +//========================================================================== + +void FTextureManager::InitSwitchList () +{ + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + int lump = Wads.CheckNumForName ("SWITCHES"); + FSwitchDef **origMap; + int i, j; + + if (lump != -1) + { + FMemLump lumpdata = Wads.ReadLump (lump); + const char *alphSwitchList = (const char *)lumpdata.GetMem(); + const char *list_p; + FSwitchDef *def1, *def2; + + for (list_p = alphSwitchList; list_p[18] || list_p[19]; list_p += 20) + { + // [RH] Check for switches that aren't really switches + if (stricmp (list_p, list_p+9) == 0) + { + Printf ("Switch %s in SWITCHES has the same 'on' state\n", list_p); + continue; + } + // [RH] Skip this switch if its textures can't be found. + if (CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags).Exists() && + CheckForTexture (list_p + 9 /* .name2 */, FTexture::TEX_Wall, texflags).Exists()) + { + def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); + def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); + def1->PreTexture = def2->u[0].Texture = CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags); + def2->PreTexture = def1->u[0].Texture = CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags); + def1->Sound = def2->Sound = 0; + def1->NumFrames = def2->NumFrames = 1; + def1->u[0].Time = def2->u[0].Time = 0; + def2->PairIndex = AddSwitchDef (def1); + def1->PairIndex = AddSwitchDef (def2); + } + } + } + + mSwitchDefs.ShrinkToFit (); + + // Sort mSwitchDefs for quick searching + origMap = new FSwitchDef *[mSwitchDefs.Size ()]; + for (i = 0; i < (int)mSwitchDefs.Size (); i++) + { + origMap[i] = mSwitchDefs[i]; + } + + qsort (&mSwitchDefs[0], i, sizeof(FSwitchDef *), SortSwitchDefs); + + // Correct the PairIndex of each switch def, since the sorting broke them + for (i = (int)(mSwitchDefs.Size () - 1); i >= 0; i--) + { + FSwitchDef *def = mSwitchDefs[i]; + if (def->PairIndex != 65535) + { + for (j = (int)(mSwitchDefs.Size () - 1); j >= 0; j--) + { + if (mSwitchDefs[j] == origMap[def->PairIndex]) + { + def->PairIndex = (WORD)j; + break; + } + } + } + } + + delete[] origMap; +} + +//========================================================================== +// +// Parse a switch block in ANIMDEFS and add the definitions to mSwitchDefs +// +//========================================================================== + +void FTextureManager::ProcessSwitchDef (FScanner &sc) +{ + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + FString picname; + FSwitchDef *def1, *def2; + FTextureID picnum; + int gametype; + bool quest = false; + + def1 = def2 = NULL; + sc.MustGetString (); + if (sc.Compare ("doom")) + { + gametype = GAME_DoomChex; + sc.CheckNumber(); // skip the gamemission filter + } + else if (sc.Compare ("heretic")) + { + gametype = GAME_Heretic; + } + else if (sc.Compare ("hexen")) + { + gametype = GAME_Hexen; + } + else if (sc.Compare ("strife")) + { + gametype = GAME_Strife; + } + else if (sc.Compare ("any")) + { + gametype = GAME_Any; + } + else + { + // There is no game specified; just treat as any + //max = 240; + gametype = GAME_Any; + sc.UnGet (); + } + + sc.MustGetString (); + picnum = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); + picname = sc.String; + while (sc.GetString ()) + { + if (sc.Compare ("quest")) + { + quest = true; + } + else if (sc.Compare ("on")) + { + if (def1 != NULL) + { + sc.ScriptError ("Switch already has an on state"); + } + def1 = ParseSwitchDef (sc, !picnum.Exists()); + } + else if (sc.Compare ("off")) + { + if (def2 != NULL) + { + sc.ScriptError ("Switch already has an off state"); + } + def2 = ParseSwitchDef (sc, !picnum.Exists()); + } + else + { + sc.UnGet (); + break; + } + } + + if (def1 == NULL || !picnum.Exists() || + (gametype != GAME_Any && !(gametype & gameinfo.gametype))) + { + if (def2 != NULL) + { + M_Free (def2); + } + if (def1 != NULL) + { + M_Free (def1); + } + return; + } + + // If the switch did not have an off state, create one that just returns + // it to the original texture without doing anything interesting + if (def2 == NULL) + { + def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); + def2->Sound = def1->Sound; + def2->NumFrames = 1; + def2->u[0].Time = 0; + def2->u[0].Texture = picnum; + } + + def1->PreTexture = picnum; + def2->PreTexture = def1->u[def1->NumFrames-1].Texture; + if (def1->PreTexture == def2->PreTexture) + { + sc.ScriptError ("The on state for switch %s must end with a texture other than %s", picname.GetChars(), picname.GetChars()); + } + def2->PairIndex = AddSwitchDef (def1); + def1->PairIndex = AddSwitchDef (def2); + def1->QuestPanel = def2->QuestPanel = quest; +} + +//========================================================================== +// +// Parse one switch frame +// +//========================================================================== + +FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad) +{ + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + FSwitchDef *def; + TArray frames; + FSwitchDef::frame thisframe; + FTextureID picnum; + bool bad; + FSoundID sound; + + bad = false; + + while (sc.GetString ()) + { + if (sc.Compare ("sound")) + { + if (sound != 0) + { + sc.ScriptError ("Switch state already has a sound"); + } + sc.MustGetString (); + sound = sc.String; + } + else if (sc.Compare ("pic")) + { + sc.MustGetString (); + picnum = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); + if (!picnum.Exists() && !ignoreBad) + { + //Printf ("Unknown switch texture %s\n", sc.String); + bad = true; + } + thisframe.Texture = picnum; + sc.MustGetString (); + if (sc.Compare ("tics")) + { + sc.MustGetNumber (); + thisframe.Time = sc.Number & 65535; + } + else if (sc.Compare ("rand")) + { + int min, max; + + sc.MustGetNumber (); + min = sc.Number & 65535; + sc.MustGetNumber (); + max = sc.Number & 65535; + if (min > max) + { + swapvalues (min, max); + } + thisframe.Time = ((max - min + 1) << 16) | min; + } + else + { + thisframe.Time = 0; // Shush, GCC. + sc.ScriptError ("Must specify a duration for switch frame"); + } + frames.Push(thisframe); + } + else + { + sc.UnGet (); + break; + } + } + if (frames.Size() == 0) + { + sc.ScriptError ("Switch state needs at least one frame"); + } + if (bad) + { + return NULL; + } + + def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, u[0]) + frames.Size()*sizeof(frames[0])); + def->Sound = sound; + def->NumFrames = frames.Size(); + memcpy (&def->u[0], &frames[0], frames.Size() * sizeof(frames[0])); + def->PairIndex = 65535; + return def; +} + +//========================================================================== +// +// +// +//========================================================================== + +WORD FTextureManager::AddSwitchDef (FSwitchDef *def) +{ + unsigned int i; + + for (i = mSwitchDefs.Size (); i-- > 0; ) + { + if (mSwitchDefs[i]->PreTexture == def->PreTexture) + { + M_Free (mSwitchDefs[i]); + mSwitchDefs[i] = def; + return (WORD)i; + } + } + return (WORD)mSwitchDefs.Push (def); +} + +//========================================================================== +// +// +// +//========================================================================== + +int FTextureManager::FindSwitch (FTextureID texture) +{ + int mid, low, high; + + high = (int)(mSwitchDefs.Size () - 1); + if (high >= 0) + { + low = 0; + do + { + mid = (high + low) / 2; + if (mSwitchDefs[mid]->PreTexture == texture) + { + return mid; + } + else if (texture < mSwitchDefs[mid]->PreTexture) + { + high = mid - 1; + } + else + { + low = mid + 1; + } + } while (low <= high); + } + return -1; +} + diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index a4f0efe0..3a75334a 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -269,7 +269,7 @@ void FTextureManager::InitAnimDefs () } else if (sc.Compare ("switch")) { - P_ProcessSwitchDef (sc); + ProcessSwitchDef (sc); } // [GRB] Added warping type 2 else if (sc.Compare ("warp") || sc.Compare ("warp2")) @@ -282,7 +282,7 @@ void FTextureManager::InitAnimDefs () } else if (sc.Compare ("animatedDoor")) { - P_ParseAnimatedDoor (sc); + ParseAnimatedDoor (sc); } else if (sc.Compare("skyoffset")) { @@ -699,6 +699,93 @@ void FTextureManager::FixAnimations () } } +//========================================================================== +// +// ParseAnimatedDoor +// +// Parses an animated door definition +// +//========================================================================== + +void FTextureManager::ParseAnimatedDoor(FScanner &sc) +{ + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + FDoorAnimation anim; + TArray frames; + bool error = false; + FTextureID v; + + sc.MustGetString(); + anim.BaseTexture = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); + + if (!anim.BaseTexture.Exists()) + { + error = true; + } + + while (sc.GetString ()) + { + if (sc.Compare ("opensound")) + { + sc.MustGetString (); + anim.OpenSound = sc.String; + } + else if (sc.Compare ("closesound")) + { + sc.MustGetString (); + anim.CloseSound = sc.String; + } + else if (sc.Compare ("pic")) + { + sc.MustGetString (); + if (IsNum (sc.String)) + { + v = anim.BaseTexture + (atoi(sc.String) - 1); + } + else + { + v = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); + if (!v.Exists() && anim.BaseTexture.Exists() && !error) + { + sc.ScriptError ("Unknown texture %s", sc.String); + } + frames.Push (v); + } + } + else + { + sc.UnGet (); + break; + } + } + if (!error) + { + anim.TextureFrames = new FTextureID[frames.Size()]; + memcpy (anim.TextureFrames, &frames[0], sizeof(FTextureID) * frames.Size()); + anim.NumTextureFrames = frames.Size(); + mAnimatedDoors.Push (anim); + } +} + +//========================================================================== +// +// Return index into "DoorAnimations" array for which door type to use +// +//========================================================================== + +FDoorAnimation *FTextureManager::FindAnimatedDoor (FTextureID picnum) +{ + unsigned int i; + + for (i = 0; i < mAnimatedDoors.Size(); ++i) + { + if (picnum == mAnimatedDoors[i].BaseTexture) + return &mAnimatedDoors[i]; + } + + return NULL; +} + //========================================================================== // // FAnimDef :: SetSwitchTime @@ -815,3 +902,4 @@ void FTextureManager::UpdateAnimations (DWORD mstime) } } } + diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 80690a03..fc49d07d 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -104,6 +104,26 @@ void FTextureManager::DeleteAll() } mAnimations.Clear(); + for (unsigned i = 0; i < mSwitchDefs.Size(); i++) + { + if (mSwitchDefs[i] != NULL) + { + M_Free (mSwitchDefs[i]); + mSwitchDefs[i] = NULL; + } + } + mSwitchDefs.Clear(); + + for (unsigned i = 0; i < mAnimatedDoors.Size(); i++) + { + if (mAnimatedDoors[i].TextureFrames != NULL) + { + delete mAnimatedDoors[i].TextureFrames; + mAnimatedDoors[i].TextureFrames = NULL; + } + } + mAnimatedDoors.Clear(); + for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i) { delete[] BuildTileFiles[i]; @@ -978,6 +998,7 @@ void FTextureManager::Init() InitAnimated(); InitAnimDefs(); FixAnimations(); + InitSwitchList(); } //========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index 2a65d1dd..7efac519 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -105,6 +105,30 @@ struct FAnimDef void SetSwitchTime (DWORD mstime); }; +struct FSwitchDef +{ + FTextureID PreTexture; // texture to switch from + WORD PairIndex; // switch def to use to return to PreTexture + WORD NumFrames; // # of animation frames + int Sound; // sound to play at start of animation. Changed to int to avoiud having to include s_sound here. + bool QuestPanel; // Special texture for Strife mission + struct frame // Array of times followed by array of textures + { // actual length of each array is + DWORD Time; + FTextureID Texture; + } u[1]; +}; + +struct FDoorAnimation +{ + FTextureID BaseTexture; + FTextureID *TextureFrames; + int NumTextureFrames; + FName OpenSound; + FName CloseSound; +}; + + // Patches. // A patch holds one or more columns. @@ -440,6 +464,14 @@ public: void UpdateAnimations (DWORD mstime); int GuesstimateNumTextures (); + int FindSwitch (FTextureID texture); + FSwitchDef *GetSwitch (unsigned int index) + { + if (index < mSwitchDefs.Size()) return mSwitchDefs[index]; + else return NULL; + } + FDoorAnimation *FindAnimatedDoor (FTextureID picnum); + private: // texture counting @@ -468,6 +500,14 @@ private: void ParseTime (FScanner &sc, DWORD &min, DWORD &max); FTexture *Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; } void SetTranslation (FTextureID fromtexnum, FTextureID totexnum); + void ParseAnimatedDoor(FScanner &sc); + + // Switches + + void InitSwitchList (); + void ProcessSwitchDef (FScanner &sc); + FSwitchDef *ParseSwitchDef (FScanner &sc, bool ignoreBad); + WORD AddSwitchDef (FSwitchDef *def); struct TextureHash { @@ -482,6 +522,8 @@ private: TArray FirstTextureForFile; TArray mAnimations; + TArray mSwitchDefs; + TArray mAnimatedDoors; TArray BuildTileFiles; }; diff --git a/src/win32/zdoom.rc b/src/win32/zdoom.rc index d6602a10..881166a8 100644 --- a/src/win32/zdoom.rc +++ b/src/win32/zdoom.rc @@ -71,7 +71,7 @@ BEGIN " VALUE ""FileDescription"", ""GZDoom""\r\n" " VALUE ""FileVersion"", RC_FILEVERSION2\r\n" " VALUE ""InternalName"", ""GZDoom""\r\n" - " VALUE ""LegalCopyright"", ""Copyright © 1993-1996, id Software, 1998-2005, Randy Heit, 2002-2006 Christoph Oelckers""\r\n" + " VALUE ""LegalCopyright"", ""Copyright © 1993-1996, id Software, 1998-2010, Randy Heit, 2002-2010 Christoph Oelckers""\r\n" " VALUE ""LegalTrademarks"", ""Doom® is a Registered Trademark of id Software, Inc.""\r\n" " VALUE ""OriginalFilename"", ""gzdoom.exe""\r\n" " VALUE ""ProductName"", ""GZDoom""\r\n" @@ -490,7 +490,7 @@ BEGIN VALUE "FileDescription", "GZDoom" VALUE "FileVersion", RC_FILEVERSION2 VALUE "InternalName", "GZDoom" - VALUE "LegalCopyright", "Copyright © 1993-1996, id Software, 1998-2005, Randy Heit, 2002-2006 Christoph Oelckers" + VALUE "LegalCopyright", "Copyright © 1993-1996, id Software, 1998-2010, Randy Heit, 2002-2010 Christoph Oelckers" VALUE "LegalTrademarks", "Doom® is a Registered Trademark of id Software, Inc." VALUE "OriginalFilename", "gzdoom.exe" VALUE "ProductName", "GZDoom" diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 5097106e..a3de2d31 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -794,9 +794,9 @@ OptionMenu "MiscOptions" { Option "Merge left+right Alt/Ctrl/Shift", "k_mergekeys", "OnOff" Option "Alt-Enter toggles fullscreen", "k_allowfullscreentoggle", "OnOff" - Option "Show IWAD selection dialog", "queryiwad", "OnOff" - StaticText " " } + Option "Show IWAD selection dialog", "queryiwad", "OnOff" + StaticText " " Option "Enable cheats from all games", "allcheats", "OnOff" Option "Enable autosaves", "disableautosave", "OffOn" Slider "Number of autosaves", "autosavecount", 1, 32, 1, 0 From e6750550a5ea8290887f2bb523f68fb6340a5816 Mon Sep 17 00:00:00 2001 From: gez Date: Tue, 14 Dec 2010 22:53:44 +0000 Subject: [PATCH 62/82] * Updated to ZDoom r3038 (IWAD selection dialog already fixed in previous commit): - Added DavidPH's submission for specifying vertex heights directly in UDMF. - Move static AM color initialization into the AM_StaticInit function. - Move D_LoadWadSettings to keysections.cpp. - Made some more data reloadable. - Data structures filled by P_SetupLevel should be cleared before loading the level. They can remain non-empty in case of an error. There's probably more to fix here... - Fixed: MidiDevices and MusicAliases were not cleared before reloading local SNDINFOs. - Fixed signed/unsigned warnings in AddSwitchPair for real (GCC really allows -1u? MSVC prints a warning for that.) - Fixed: GCC compiler warnings. - Zipdir will no longer store files ending in '~' on Linux. - Added st_oldouch which restores the old ouch face behavior of only showing when health increases by 20 while taking damage. - Changed some data init code to delete the data it wants to initialize first. - The 'savebuffer' variable still existed? - Changed AInventory::Destroy to NULL SendItemUse and SendItemDrop if they point to the destroyed object. Although unlikely it can't be ruled out completely that this can happen with delayed CCMDs. - Fixed: Starting a new game did not clear the hub statistics array. - Cleaned up D_DoomMain a little. It's still far too large though. - Added explicit initialization of console background texture instead of letting C_InitConsole doing it as needed. - Added 'clearaliases' CCMD. - Init bot specific actor properties right after parsing DECORATE, not when spawning the first bot (which is too late.) - Changed automap initialization so that static data only gets initialized once upon startup instead of each time a level starts. - Initialize AUTOPAGE only once when the level starts, not each time the automap is switched on. - Cleaned up switch code and fixed several problems: * savegames stored an index in the switch table and performed no validation when loading a savegame. * setting of a random switch animation duration was broken. * separated the 2 values stored in the Time variable into 2 separate variables. * defining a switch with one texture already belonging to another switch could leave broken definitions in the switch table. - Added function for serializing switch and door animation pointers. - Bumped min. savegame versions due to changes to DButtonThinker and removed all current savegame compatibility code. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1128 b0f79afe-0144-0410-b225-9a4edf0717df --- specs/udmf_zdoom.txt | 11 +- src/actor.h | 7 +- src/am_map.cpp | 103 +++++------ src/am_map.h | 3 + src/b_bot.cpp | 5 - src/b_game.cpp | 3 - src/c_console.cpp | 44 ++--- src/c_console.h | 1 + src/c_dispatch.cpp | 24 +++ src/c_dispatch.h | 1 + src/compatibility.cpp | 3 + src/d_iwad.cpp | 1 + src/d_main.cpp | 314 ++++++++++++++------------------ src/d_netinfo.cpp | 8 +- src/decallib.cpp | 10 + src/dobject.cpp | 5 - src/farchive.h | 4 + src/g_game.cpp | 2 - src/g_game.h | 2 + src/g_hub.cpp | 7 +- src/g_level.cpp | 2 +- src/g_level.h | 1 + src/g_mapinfo.cpp | 6 + src/g_shared/a_pickups.cpp | 5 + src/g_shared/a_quake.cpp | 12 +- src/g_shared/a_skies.cpp | 5 - src/g_shared/sbar_mugshot.cpp | 8 +- src/gi.cpp | 4 +- src/info.cpp | 5 + src/keysections.cpp | 76 ++++++++ src/menu/menu.cpp | 1 - src/namedef.h | 2 + src/p_conversation.cpp | 5 + src/p_doors.cpp | 23 +-- src/p_mobj.cpp | 112 ++---------- src/p_pspr.cpp | 12 +- src/p_saveg.cpp | 31 +--- src/p_setup.cpp | 8 + src/p_slopes.cpp | 21 +++ src/p_states.cpp | 1 - src/p_switch.cpp | 95 +++++----- src/p_terrain.cpp | 2 + src/p_udmf.cpp | 25 ++- src/p_user.cpp | 34 +--- src/r_defs.h | 10 + src/r_interpolate.cpp | 11 +- src/r_state.h | 2 + src/r_things.cpp | 1 + src/s_advsound.cpp | 9 +- src/s_sound.cpp | 4 +- src/s_sound.h | 2 +- src/statistics.cpp | 1 + src/svnrevision.h | 4 +- src/teaminfo.cpp | 1 + src/textures/anim_switches.cpp | 139 ++++++++------ src/textures/animations.cpp | 21 +++ src/textures/texturemanager.cpp | 3 - src/textures/textures.h | 18 +- src/thingdef/thingdef.cpp | 1 + src/thingdef/thingdef_data.cpp | 3 + src/version.h | 7 +- tools/zipdir/zipdir.c | 6 + wadsrc/static/menudef.txt | 1 + 63 files changed, 668 insertions(+), 630 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 1a4dbeff..6c2fde91 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -1,5 +1,5 @@ =============================================================================== -Universal Doom Map Format ZDoom extensions v1.10 - 25.04.2010 +Universal Doom Map Format ZDoom extensions v1.15 - 14.12.2010 Copyright (c) 2008 Christoph Oelckers. @@ -84,6 +84,12 @@ field to 'strifeally', even for the 'Doom' namespace. In addition to the standard fields, ZDoom defines the following: Note: All fields default to false unless mentioned otherwise. + vertex + { + zfloor = ; // Floor height at this vertex. Only applies to triangular sectors + zceiling = ; // Ceiling height at this vertex. Only applies to triangular sectors + } + linedef { alpha = ; // Translucency of this line, default is 1.0 @@ -283,6 +289,9 @@ Added 'hidden' sector property. 1.14 19.09.2010 Added 'countsecret' actor property. +1.15 14.12.2010 +Added vertex floor and ceiling height properties + =============================================================================== EOF =============================================================================== diff --git a/src/actor.h b/src/actor.h index 635198b4..35d40112 100644 --- a/src/actor.h +++ b/src/actor.h @@ -529,7 +529,12 @@ struct FDropItem class FDropItemPtrArray : public TArray { public: - ~FDropItemPtrArray(); + ~FDropItemPtrArray() + { + Clear(); + } + + void Clear(); }; extern FDropItemPtrArray DropItemList; diff --git a/src/am_map.cpp b/src/am_map.cpp index cf887615..5eb759ee 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -64,6 +64,12 @@ #include "po_man.h" #include "a_keys.h" +//============================================================================= +// +// Automap colors +// +//============================================================================= + struct AMColor { int Index; @@ -119,6 +125,12 @@ static BYTE RavenPaletteVals[11*3] = 0, 0, 0, 0, 0, 0, }; +//============================================================================= +// +// globals +// +//============================================================================= + #define MAPBITS 12 #define MapDiv SafeDivScale12 #define MapMul MulScale12 @@ -287,28 +299,28 @@ struct islope_t // A line drawing of the player pointing right, // starting from the middle. // -TArray MapArrow; -TArray CheatMapArrow; -TArray CheatKey; +static TArray MapArrow; +static TArray CheatMapArrow; +static TArray CheatKey; #define R (MAPUNIT) // [RH] Avoid lots of warnings without compiler-specific #pragmas #define L(a,b,c,d) { {(fixed_t)((a)*R),(fixed_t)((b)*R)}, {(fixed_t)((c)*R),(fixed_t)((d)*R)} } -mline_t triangle_guy[] = { +static mline_t triangle_guy[] = { L (-.867,-.5, .867,-.5), L (.867,-.5, 0,1), L (0,1, -.867,-.5) }; #define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t)) -mline_t thintriangle_guy[] = { +static mline_t thintriangle_guy[] = { L (-.5,-.7, 1,0), L (1,0, -.5,.7), L (-.5,.7, -.5,-.7) }; #define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t)) -mline_t square_guy[] = { +static mline_t square_guy[] = { L (0,1,1,0), L (1,0,0,-1), L (0,-1,-1,0), @@ -332,8 +344,6 @@ CUSTOM_CVAR (Int, am_cheat, 0, 0) static int grid = 0; -static int leveljuststarted = 1; // kluge until AM_LevelInit() is called - bool automapactive = false; // location of window on screen @@ -515,16 +525,41 @@ void AM_ParseArrow(TArray &Arrow, const char *lumpname) } } -void AM_InitArrows() +void AM_StaticInit() { - MapArrow.Clear(); CheatMapArrow.Clear(); + CheatKey.Clear(); if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow); if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow); AM_ParseArrow(CheatKey, "maparrows/key.txt"); if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined"); + + char namebuf[9]; + + for (int i = 0; i < 10; i++) + { + mysnprintf (namebuf, countof(namebuf), "AMMNUM%d", i); + marknums[i] = TexMan.CheckForTexture (namebuf, FTexture::TEX_MiscPatch); + } + markpointnum = 0; + mapback.SetInvalid(); + + static DWORD *lastpal = NULL; + //static int lastback = -1; + DWORD *palette; + + palette = (DWORD *)GPalette.BaseColors; + + int i, j; + + for (i = j = 0; i < 11; i++, j += 3) + { + DoomColors[i].FromRGB(DoomPaletteVals[j], DoomPaletteVals[j+1], DoomPaletteVals[j+2]); + StrifeColors[i].FromRGB(StrifePaletteVals[j], StrifePaletteVals[j+1], StrifePaletteVals[j+2]); + RavenColors[i].FromRGB(RavenPaletteVals[j], RavenPaletteVals[j+1], RavenPaletteVals[j+2]); + } } //============================================================================= @@ -858,24 +893,6 @@ void AM_initVariables () static void AM_initColors (bool overlayed) { - static DWORD *lastpal = NULL; - //static int lastback = -1; - DWORD *palette; - - palette = (DWORD *)GPalette.BaseColors; - - if (lastpal != palette) - { - int i, j; - - for (i = j = 0; i < 11; i++, j += 3) - { - DoomColors[i].FromRGB(DoomPaletteVals[j], DoomPaletteVals[j+1], DoomPaletteVals[j+2]); - StrifeColors[i].FromRGB(StrifePaletteVals[j], StrifePaletteVals[j+1], StrifePaletteVals[j+2]); - RavenColors[i].FromRGB(RavenPaletteVals[j], RavenPaletteVals[j+1], RavenPaletteVals[j+2]); - } - } - if (overlayed) { YourColor.FromCVar (am_ovyourcolor); @@ -1000,30 +1017,6 @@ static void AM_initColors (bool overlayed) break; } - - lastpal = palette; -} - -//============================================================================= -// -// -// -//============================================================================= - -void AM_loadPics () -{ - int i; - char namebuf[9]; - - for (i = 0; i < 10; i++) - { - mysnprintf (namebuf, countof(namebuf), "AMMNUM%d", i); - marknums[i] = TexMan.CheckForTexture (namebuf, FTexture::TEX_MiscPatch); - } - - const char *autopage = level.info->mapbg[0] == 0? "AUTOPAGE" : (const char*)&level.info->mapbg[0]; - - mapback = TexMan.CheckForTexture(autopage, FTexture::TEX_MiscPatch); } //============================================================================= @@ -1048,9 +1041,8 @@ bool AM_clearMarks () void AM_LevelInit () { - if (MapArrow.Size() == 0) AM_InitArrows(); - - leveljuststarted = 0; + const char *autopage = level.info->mapbg[0] == 0? "AUTOPAGE" : (const char*)&level.info->mapbg[0]; + mapback = TexMan.CheckForTexture(autopage, FTexture::TEX_MiscPatch); AM_clearMarks(); @@ -1088,7 +1080,6 @@ void AM_Start () if (!stopped) AM_Stop(); stopped = false; AM_initVariables(); - AM_loadPics(); } diff --git a/src/am_map.h b/src/am_map.h index 20da6b96..e4fe5085 100644 --- a/src/am_map.h +++ b/src/am_map.h @@ -25,6 +25,9 @@ struct event_t; class FArchive; + +void AM_StaticInit(); + // Called by main loop. bool AM_Responder (event_t* ev, bool last); diff --git a/src/b_bot.cpp b/src/b_bot.cpp index cee4086a..eaa71c0e 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -105,11 +105,6 @@ FArchive &operator<< (FArchive &arc, botskill_t &skill) // This is intentionally not in the weapon definition anymore. void InitBotStuff() { - static bool done = false; - - if (done) return; - done = true; - static struct BotInit { const char *type; diff --git a/src/b_game.cpp b/src/b_game.cpp index f517f27e..2ff74a28 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -63,8 +63,6 @@ Everything that is changed is marked (maybe commented) with "Added by MC" static FRandom pr_botspawn ("BotSpawn"); -void InitBotStuff(); - //Externs FCajunMaster bglobal; @@ -321,7 +319,6 @@ bool FCajunMaster::SpawnBot (const char *name, int color) waitingforspawn[playernumber] = true; - InitBotStuff(); Net_WriteByte (DEM_ADDBOT); Net_WriteByte (playernumber); { diff --git a/src/c_console.cpp b/src/c_console.cpp index 324fad66..c19ff3f2 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -94,7 +94,7 @@ extern FBaseCVar *CVars; extern FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; int ConCols, PhysRows; -bool vidactive = false, gotconback = false; +bool vidactive = false; bool cursoron = false; int ConBottom, ConScroll, RowAdjust; int CursorTicker; @@ -232,7 +232,7 @@ CUSTOM_CVAR (Int, msgmidcolor2, 4, CVAR_ARCHIVE) static void maybedrawnow (bool tick, bool force) { // FIXME: Does not work right with hw2d - if (ConsoleDrawing || !gotconback || screen == NULL || screen->IsLocked () || screen->Accel2D) + if (ConsoleDrawing || screen == NULL || screen->IsLocked () || screen->Accel2D || ConFont == NULL) { return; } @@ -297,32 +297,28 @@ void DequeueConsoleText () EnqueuedTextTail = &EnqueuedText; } +void C_InitConback() +{ + conback = TexMan.CheckForTexture ("CONBACK", FTexture::TEX_MiscPatch); + + if (!conback.isValid()) + { + conback = TexMan.GetTexture (gameinfo.titlePage, FTexture::TEX_MiscPatch); + conshade = MAKEARGB(175,0,0,0); + conline = true; + } + else + { + conshade = 0; + conline = false; + } +} + void C_InitConsole (int width, int height, bool ingame) { - if ( (vidactive = ingame) ) - { - if (!gotconback) - { - conback = TexMan.CheckForTexture ("CONBACK", FTexture::TEX_MiscPatch); - - if (!conback.isValid()) - { - conback = TexMan.GetTexture (gameinfo.titlePage, FTexture::TEX_MiscPatch); - conshade = MAKEARGB(175,0,0,0); - conline = true; - } - else - { - conshade = 0; - conline = false; - } - - gotconback = true; - } - } - int cwidth, cheight; + vidactive = ingame; if (ConFont != NULL) { cwidth = ConFont->GetCharWidth ('M'); diff --git a/src/c_console.h b/src/c_console.h index e1434c05..8560d677 100644 --- a/src/c_console.h +++ b/src/c_console.h @@ -53,6 +53,7 @@ extern int ConBottom; // Initialize the console void C_InitConsole (int width, int height, bool ingame); void C_DeinitConsole (); +void C_InitConback(); // Adjust the console for a new screen mode void C_NewModeAdjust (void); diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 413b8d64..1a2b3158 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -1211,6 +1211,30 @@ void C_ArchiveAliases (FConfigFile *f) } } +void C_ClearAliases () +{ + int bucket; + FConsoleCommand *alias; + + for (bucket = 0; bucket < FConsoleCommand::HASH_SIZE; bucket++) + { + alias = Commands[bucket]; + while (alias) + { + FConsoleCommand *next = alias->m_Next; + if (alias->IsAlias()) + static_cast(alias)->SafeDelete(); + alias = next; + } + } +} + +CCMD(clearaliases) +{ + C_ClearAliases(); +} + + // This is called only by the ini parser. void C_SetAlias (const char *name, const char *cmd) { diff --git a/src/c_dispatch.h b/src/c_dispatch.h index d93709c9..ac868585 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -58,6 +58,7 @@ int C_ExecFile (const char *cmd, bool usePullin); void C_ArchiveAliases (FConfigFile *f); void C_SetAlias (const char *name, const char *cmd); +void C_ClearAliases (); // build a single string out of multiple strings FString BuildString (int argc, char **argv); diff --git a/src/compatibility.cpp b/src/compatibility.cpp index bfd5ae32..cd74f5e3 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -143,6 +143,9 @@ void ParseCompatibility() int i, x; unsigned int j; + BCompatMap.Clear(); + CompatParams.Clear(); + // The contents of this file are not cumulative, as it should not // be present in user-distributed maps. FScanner sc(Wads.GetNumForFullName("compatibility.txt")); diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index b02407b1..0c7cc3bf 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -549,6 +549,7 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, exit (0); // zdoom.pk3 must always be the first file loaded and the IWAD second. + wadfiles.Clear(); D_AddFile (wadfiles, zdoom_wad); if (mIWads[wads[pickwad].Type].preload >= 0) diff --git a/src/d_main.cpp b/src/d_main.cpp index fd03a5c4..2eaabf76 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -131,6 +131,7 @@ void D_ProcessEvents (); void G_BuildTiccmd (ticcmd_t* cmd); void D_DoAdvanceDemo (); void D_AddWildFile (TArray &wadfiles, const char *pattern); +void D_LoadWadSettings (); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- @@ -926,6 +927,7 @@ void D_DoomLoop () // Clamp the timer to TICRATE until the playloop has been entered. r_NoInterpolate = true; + Page = Advisory = NULL; vid_cursor.Callback(); @@ -1562,80 +1564,6 @@ bool ConsiderPatches (const char *arg) return argc > 0; } -//========================================================================== -// -// D_LoadWadSettings -// -// Parses any loaded KEYCONF lumps. These are restricted console scripts -// that can only execute the alias, defaultbind, addkeysection, -// addmenukey, weaponsection, and addslotdefault commands. -// -//========================================================================== - -void D_LoadWadSettings () -{ - char cmd[4096]; - int lump, lastlump = 0; - - ParsingKeyConf = true; - - while ((lump = Wads.FindLump ("KEYCONF", &lastlump)) != -1) - { - FMemLump data = Wads.ReadLump (lump); - const char *eof = (char *)data.GetMem() + Wads.LumpLength (lump); - const char *conf = (char *)data.GetMem(); - - while (conf < eof) - { - size_t i; - - // Fetch a line to execute - for (i = 0; conf + i < eof && conf[i] != '\n'; ++i) - { - cmd[i] = conf[i]; - } - cmd[i] = 0; - conf += i; - if (*conf == '\n') - { - conf++; - } - - // Comments begin with // - char *stop = cmd + i - 1; - char *comment = cmd; - int inQuote = 0; - - if (*stop == '\r') - *stop-- = 0; - - while (comment < stop) - { - if (*comment == '\"') - { - inQuote ^= 1; - } - else if (!inQuote && *comment == '/' && *(comment + 1) == '/') - { - break; - } - comment++; - } - if (comment == cmd) - { // Comment at line beginning - continue; - } - else if (comment < stop) - { // Comment in middle of line - *comment = 0; - } - - AddCommandString (cmd); - } - } - ParsingKeyConf = false; -} - //========================================================================== // // D_MultiExec @@ -1818,20 +1746,12 @@ static void SetMapxxFlag() //========================================================================== // -// D_DoomMain +// Initialize // //========================================================================== -void D_DoomMain (void) +static void D_DoomInit() { - int p, flags; - const char *v; - const char *wad; - DArgs *execFiles; - TArray pwads; - FString *args; - int argcount; - // Set the FPU precision to 53 significant bits. This is the default // for Visual C++, but not for GCC, so some slight math variances // might crop up if we leave it alone. @@ -1859,7 +1779,6 @@ void D_DoomMain (void) Args->CollectFiles("-playdemo", ".lmp"); Args->CollectFiles("-file", NULL); // anything left goes after -file - PClass::StaticInit (); atterm (C_DeinitConsole); gamestate = GS_STARTUP; @@ -1872,30 +1791,16 @@ void D_DoomMain (void) Printf ("M_LoadDefaults: Load system defaults.\n"); M_LoadDefaults (); // load before initing other systems - // [RH] Make sure zdoom.pk3 is always loaded, - // as it contains magic stuff we need. +} - wad = BaseFileSearch (BASEWAD, NULL, true); - if (wad == NULL) - { - I_FatalError ("Cannot find " BASEWAD); - } - FString basewad = wad; - - // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before - // the IWAD is known. - - GetCmdLineFiles(pwads); - FString iwad = CheckGameInfo(pwads); - - FIWadManager *iwad_man = new FIWadManager; - const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); - gameinfo.gametype = iwad_info->gametype; - gameinfo.flags = iwad_info->flags; - gameinfo.ConfigName = iwad_info->Configname; - - GameConfig->DoGameSetup (gameinfo.ConfigName); +//========================================================================== +// +// AddAutoloadFiles +// +//========================================================================== +static void AddAutoloadFiles(const char *gamesection) +{ if (!(gameinfo.flags & GI_SHAREWARE) && !Args->CheckParm("-noautoload")) { FString file; @@ -1905,7 +1810,7 @@ void D_DoomMain (void) // voices. I never got around to writing the utility to do it, though. // And I probably never will now. But I know at least one person uses // it for something else, so this gets to stay here. - wad = BaseFileSearch ("zvox.wad", NULL); + const char *wad = BaseFileSearch ("zvox.wad", NULL); if (wad) D_AddFile (allwads, wad); @@ -1932,66 +1837,28 @@ void D_DoomMain (void) D_AddConfigWads (allwads, file); // Add IWAD-specific wads - if (iwad_info->Autoname != NULL) + if (gamesection != NULL) { - file = iwad_info->Autoname; + file = gamesection; file += ".Autoload"; D_AddConfigWads(allwads, file); } } +} - // Run automatically executed files - execFiles = new DArgs; - GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName); - D_MultiExec (execFiles, true); +//========================================================================== +// +// CheckCmdLine +// +//========================================================================== - // Run .cfg files at the start of the command line. - execFiles = Args->GatherFiles ("-exec"); - D_MultiExec (execFiles, true); +static void CheckCmdLine() +{ + int flags = dmflags; + int p; + const char *v; - C_ExecCmdLineParams (); // [RH] do all +set commands on the command line - - CopyFiles(allwads, pwads); - - // Since this function will never leave we must delete this array here manually. - pwads.Clear(); - pwads.ShrinkToFit(); - - Printf ("W_Init: Init WADfiles.\n"); - Wads.InitMultipleFiles (allwads); - allwads.Clear(); - allwads.ShrinkToFit(); - SetMapxxFlag(); - - // [RH] Initialize localizable strings. - GStrings.LoadStrings (false); - - V_InitFontColors (); - - // [RH] Moved these up here so that we can do most of our - // startup output in a fullscreen console. - - CT_Init (); - - Printf ("I_Init: Setting up machine state.\n"); - I_Init (); - - Printf ("V_Init: allocate screen.\n"); - V_Init (); - - // Base systems have been inited; enable cvar callbacks - FBaseCVar::EnableCallbacks (); - - Printf ("S_Init: Setting up sound.\n"); - S_Init (); - - Printf ("ST_Init: Init startup screen.\n"); - StartScreen = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5); - - ParseCompatibility(); - - Printf ("P_Init: Checking cmd-line parameters...\n"); - flags = dmflags; + Printf ("Checking cmd-line parameters...\n"); if (Args->CheckParm ("-nomonsters")) flags |= DF_NO_MONSTERS; if (Args->CheckParm ("-respawn")) flags |= DF_MONSTERS_RESPAWN; if (Args->CheckParm ("-fast")) flags |= DF_FAST_MONSTERS; @@ -2126,6 +1993,104 @@ void D_DoomMain (void) temp.Format ("Warp to map %s, Skill %d ", startmap.GetChars(), gameskill + 1); StartScreen->AppendStatusLine(temp); } +} + +//========================================================================== +// +// D_DoomMain +// +//========================================================================== + +void D_DoomMain (void) +{ + int p; + const char *v; + const char *wad; + DArgs *execFiles; + TArray pwads; + FString *args; + int argcount; + + D_DoomInit(); + PClass::StaticInit (); + + // [RH] Make sure zdoom.pk3 is always loaded, + // as it contains magic stuff we need. + + wad = BaseFileSearch (BASEWAD, NULL, true); + if (wad == NULL) + { + I_FatalError ("Cannot find " BASEWAD); + } + FString basewad = wad; + + // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before + // the IWAD is known. + + GetCmdLineFiles(pwads); + FString iwad = CheckGameInfo(pwads); + + FIWadManager *iwad_man = new FIWadManager; + const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); + gameinfo.gametype = iwad_info->gametype; + gameinfo.flags = iwad_info->flags; + gameinfo.ConfigName = iwad_info->Configname; + + GameConfig->DoGameSetup (gameinfo.ConfigName); + + AddAutoloadFiles(iwad_info->Autoname); + + // Run automatically executed files + execFiles = new DArgs; + GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName); + D_MultiExec (execFiles, true); + + // Run .cfg files at the start of the command line. + execFiles = Args->GatherFiles ("-exec"); + D_MultiExec (execFiles, true); + + C_ExecCmdLineParams (); // [RH] do all +set commands on the command line + + CopyFiles(allwads, pwads); + + // Since this function will never leave we must delete this array here manually. + pwads.Clear(); + pwads.ShrinkToFit(); + + Printf ("W_Init: Init WADfiles.\n"); + Wads.InitMultipleFiles (allwads); + allwads.Clear(); + allwads.ShrinkToFit(); + SetMapxxFlag(); + + // [RH] Initialize localizable strings. + GStrings.LoadStrings (false); + + V_InitFontColors (); + + // [RH] Moved these up here so that we can do most of our + // startup output in a fullscreen console. + + CT_Init (); + + Printf ("I_Init: Setting up machine state.\n"); + I_Init (); + + Printf ("V_Init: allocate screen.\n"); + V_Init (); + + // Base systems have been inited; enable cvar callbacks + FBaseCVar::EnableCallbacks (); + + Printf ("S_Init: Setting up sound.\n"); + S_Init (); + + Printf ("ST_Init: Init startup screen.\n"); + StartScreen = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5); + + ParseCompatibility(); + + CheckCmdLine(); // [RH] Load sound environments S_ParseReverbDef (); @@ -2141,6 +2106,7 @@ void D_DoomMain (void) Printf ("Texman.Init: Init texture manager.\n"); TexMan.Init(); + C_InitConback(); // [CW] Parse any TEAMINFO lumps. Printf ("ParseTeamInfo: Load team definitions.\n"); @@ -2199,20 +2165,8 @@ void D_DoomMain (void) FActorInfo::StaticSetActorNums (); - // [RH] User-configurable startup strings. Because BOOM does. - static const char *startupString[5] = { - "STARTUP1", "STARTUP2", "STARTUP3", "STARTUP4", "STARTUP5" - }; - for (p = 0; p < 5; ++p) - { - const char *str = GStrings[startupString[p]]; - if (str != NULL && str[0] != '\0') - { - Printf ("%s\n", str); - } - } - //Added by MC: + bglobal.getspawned.Clear(); argcount = Args->CheckParmList("-bots", &args); for (p = 0; p < argcount; ++p) { @@ -2226,6 +2180,7 @@ void D_DoomMain (void) Printf ("P_Init: Init Playloop state.\n"); StartScreen->LoadingStatus ("Init game engine", 0x3f); + AM_StaticInit(); P_Init (); P_SetupWeapons_ntohton(); @@ -2233,6 +2188,19 @@ void D_DoomMain (void) //SBarInfo support. SBarInfo::Load(); + // [RH] User-configurable startup strings. Because BOOM does. + static const char *startupString[5] = { + "STARTUP1", "STARTUP2", "STARTUP3", "STARTUP4", "STARTUP5" + }; + for (p = 0; p < 5; ++p) + { + const char *str = GStrings[startupString[p]]; + if (str != NULL && str[0] != '\0') + { + Printf ("%s\n", str); + } + } + Printf ("D_CheckNetGame: Checking network game status.\n"); StartScreen->LoadingStatus ("Checking network game status.", 0x3f); D_CheckNetGame (); diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 51467369..def80065 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -835,11 +835,9 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info) { arc.Read (&info.netname, sizeof(info.netname)); } - arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch; - if (SaveVersion >= 2193) - { - arc << info.colorset; - } + arc << info.team << info.aimdist << info.color + << info.skin << info.gender << info.neverswitch + << info.colorset; return arc; } diff --git a/src/decallib.cpp b/src/decallib.cpp index bfcc1ac1..6bbf0f74 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -347,6 +347,16 @@ void FDecalLib::ReadAllDecals () int lump, lastlump = 0; unsigned int i; + for(unsigned i=0;iSymbols; if (arc.IsStoring()) diff --git a/src/farchive.h b/src/farchive.h index 533b3920..7ee05fdc 100644 --- a/src/farchive.h +++ b/src/farchive.h @@ -291,7 +291,11 @@ template<> inline FArchive &operator<< (FArchive &arc, FFont* &font) } struct FStrifeDialogueNode; +struct FSwitchDef; +struct FDoorAnimation; template<> FArchive &operator<< (FArchive &arc, FStrifeDialogueNode *&node); +template<> FArchive &operator<< (FArchive &arc, FSwitchDef* &sw); +template<> FArchive &operator<< (FArchive &arc, FDoorAnimation* &da); diff --git a/src/g_game.cpp b/src/g_game.cpp index 19acf8c5..e10936f9 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -180,8 +180,6 @@ wbstartstruct_t wminfo; // parms for world map / intermission short consistancy[MAXPLAYERS][BACKUPTICS]; -BYTE* savebuffer; - #define MAXPLMOVE (forwardmove[1]) diff --git a/src/g_game.h b/src/g_game.h index 20fdae89..a9f5f0af 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -85,6 +85,8 @@ void G_AddViewAngle (int yaw); class AActor; extern AActor *bodyque[BODYQUESIZE]; extern int bodyqueslot; +class AInventory; +extern const AInventory *SendItemUse, *SendItemDrop; #endif diff --git a/src/g_hub.cpp b/src/g_hub.cpp index 162aacd1..22c6ff6f 100644 --- a/src/g_hub.cpp +++ b/src/g_hub.cpp @@ -76,7 +76,7 @@ struct FHubInfo }; -TArray hubdata; +static TArray hubdata; void G_LeavingHub(int mode, cluster_info_t * cluster, wbstartstruct_t * wbs) { @@ -182,3 +182,8 @@ void G_ReadHubInfo (PNGHandle *png) G_SerializeHub(arc); } } + +void G_ClearHubInfo() +{ + hubdata.Clear(); +} \ No newline at end of file diff --git a/src/g_level.cpp b/src/g_level.cpp index e3321f88..a962d519 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -119,7 +119,6 @@ bool savegamerestore; extern int mousex, mousey; extern bool sendpause, sendsave, sendturn180, SendLand; -extern const AInventory *SendItemUse, *SendItemDrop; void *statcopy; // for statistics driver @@ -309,6 +308,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) bool wantFast; int i; + G_ClearHubInfo(); if (!savegamerestore) { G_ClearSnapshots (); diff --git a/src/g_level.h b/src/g_level.h index d7add35b..6cb9d844 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -514,6 +514,7 @@ void G_UnSnapshotLevel (bool keepPlayers); struct PNGHandle; void G_ReadSnapshots (PNGHandle *png); void G_WriteSnapshots (FILE *file); +void G_ClearHubInfo(); enum ESkillProperty { diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index adf0b2cd..4199305d 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1803,8 +1803,13 @@ void DeinitIntermissions(); static void ClearMapinfo() { + wadclusterinfos.Clear(); + wadlevelinfos.Clear(); ClearEpisodes(); + AllSkills.Clear(); + DefaultSkill = -1; DeinitIntermissions(); + level.info = NULL; } //========================================================================== @@ -1820,6 +1825,7 @@ void G_ParseMapInfo (const char *basemapinfo) int lump, lastlump = 0; level_info_t gamedefaults; + ClearMapinfo(); atterm(ClearMapinfo); // Parse the default MAPINFO for the current game. This lump *MUST* come from zdoom.pk3. diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 524daee7..f059d8d3 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -16,6 +16,7 @@ #include "a_specialspot.h" #include "thingdef/thingdef.h" #include "g_level.h" +#include "g_game.h" #include "doomstat.h" static FRandom pr_restore ("RestorePos"); @@ -1033,6 +1034,10 @@ void AInventory::Destroy () } Inventory = NULL; Super::Destroy (); + + // Although contrived it can theoretically happen that these variables still got a pointer to this item + if (SendItemUse == this) SendItemUse = NULL; + if (SendItemDrop == this) SendItemDrop = NULL; } //=========================================================================== diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index c5360533..725f1204 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -55,16 +55,8 @@ void DEarthquake::Serialize (FArchive &arc) { Super::Serialize (arc); arc << m_Spot << m_Intensity << m_Countdown - << m_TremorRadius << m_DamageRadius; - - if (SaveVersion >= 1912) - { - arc << m_QuakeSFX; - } - else - { - m_QuakeSFX = "world/quake"; - } + << m_TremorRadius << m_DamageRadius + << m_QuakeSFX; } //========================================================================== diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp index 21edd2ba..bb13eac0 100644 --- a/src/g_shared/a_skies.cpp +++ b/src/g_shared/a_skies.cpp @@ -70,11 +70,6 @@ void ASkyViewpoint::Serialize (FArchive &arc) { Super::Serialize (arc); arc << bInSkybox << bAlways << Mate; - if (SaveVersion < 2992) - { - fixed_t eatme; - arc << eatme; - } } void ASkyViewpoint::Destroy () diff --git a/src/g_shared/sbar_mugshot.cpp b/src/g_shared/sbar_mugshot.cpp index e48a047b..02b72167 100644 --- a/src/g_shared/sbar_mugshot.cpp +++ b/src/g_shared/sbar_mugshot.cpp @@ -335,6 +335,7 @@ bool FMugShot::SetState(const char *state_name, bool wait_till_done, bool reset) // //=========================================================================== +CVAR(Bool,st_oldouch,false,CVAR_ARCHIVE) int FMugShot::UpdateState(player_t *player, StateFlags stateflags) { int i; @@ -357,9 +358,10 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) } } + bool ouch = (!st_oldouch && FaceHealth - player->health > ST_MUCHPAIN) || (st_oldouch && player->health - FaceHealth > ST_MUCHPAIN); if (player->damagecount && // Now go in if pain is disabled but we think ouch will be shown (and ouch is not disabled!) - (!(stateflags & DISABLEPAIN) || (((FaceHealth != -1 && FaceHealth - player->health > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DISABLEOUCH)))) + (!(stateflags & DISABLEPAIN) || (((FaceHealth != -1 && ouch) || bOuchActive) && !(stateflags & DISABLEOUCH)))) { int damage_angle = 1; if (player->attacker && player->attacker != player->mo) @@ -391,7 +393,7 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) } } bool use_ouch = false; - if (((FaceHealth != -1 && FaceHealth - player->health > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DISABLEOUCH)) + if (((FaceHealth != -1 && ouch) || bOuchActive) && !(stateflags & DISABLEOUCH)) { use_ouch = true; full_state_name = "ouch."; @@ -418,7 +420,7 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) else { bool use_ouch = false; - if (((FaceHealth != -1 && player->health - FaceHealth > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DISABLEOUCH)) + if (((FaceHealth != -1 && ouch) || bOuchActive) && !(stateflags & DISABLEOUCH)) { use_ouch = true; full_state_name = "ouch."; diff --git a/src/gi.cpp b/src/gi.cpp index 705f9b80..0e010724 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -77,7 +77,7 @@ static gameborder_t StrifeBorder = // Custom GAMEINFO ------------------------------------------------------------ -const char* GameInfoBoarders[] = +const char* GameInfoBorders[] = { "DoomBorder", "HereticBorder", @@ -219,7 +219,7 @@ void FMapInfoParser::ParseGameInfo() { if(sc.CheckToken(TK_Identifier)) { - switch(sc.MustMatchString(GameInfoBoarders)) + switch(sc.MustMatchString(GameInfoBorders)) { default: gameinfo.border = &DoomBorder; diff --git a/src/info.cpp b/src/info.cpp index 1b49ce7d..32aa92a9 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -52,6 +52,8 @@ #include "g_level.h" extern void LoadActors (); +extern void InitBotStuff(); +extern void ClearStrifeTypes(); //========================================================================== @@ -100,6 +102,7 @@ int GetSpriteIndex(const char * spritename) void FActorInfo::StaticInit () { + sprites.Clear(); if (sprites.Size() == 0) { spritedef_t temp; @@ -120,7 +123,9 @@ void FActorInfo::StaticInit () } Printf ("LoadActors: Load actor definitions.\n"); + ClearStrifeTypes(); LoadActors (); + InitBotStuff(); } //========================================================================== diff --git a/src/keysections.cpp b/src/keysections.cpp index 6ef0538f..bfec4060 100644 --- a/src/keysections.cpp +++ b/src/keysections.cpp @@ -41,6 +41,7 @@ #include "c_bind.h" #include "c_dispatch.h" #include "gameconfigfile.h" +#include "w_wad.h" TArray KeySections; @@ -141,3 +142,78 @@ CCMD (addmenukey) } } +//========================================================================== +// +// D_LoadWadSettings +// +// Parses any loaded KEYCONF lumps. These are restricted console scripts +// that can only execute the alias, defaultbind, addkeysection, +// addmenukey, weaponsection, and addslotdefault commands. +// +//========================================================================== + +void D_LoadWadSettings () +{ + char cmd[4096]; + int lump, lastlump = 0; + + ParsingKeyConf = true; + KeySections.Clear(); + + while ((lump = Wads.FindLump ("KEYCONF", &lastlump)) != -1) + { + FMemLump data = Wads.ReadLump (lump); + const char *eof = (char *)data.GetMem() + Wads.LumpLength (lump); + const char *conf = (char *)data.GetMem(); + + while (conf < eof) + { + size_t i; + + // Fetch a line to execute + for (i = 0; conf + i < eof && conf[i] != '\n'; ++i) + { + cmd[i] = conf[i]; + } + cmd[i] = 0; + conf += i; + if (*conf == '\n') + { + conf++; + } + + // Comments begin with // + char *stop = cmd + i - 1; + char *comment = cmd; + int inQuote = 0; + + if (*stop == '\r') + *stop-- = 0; + + while (comment < stop) + { + if (*comment == '\"') + { + inQuote ^= 1; + } + else if (!inQuote && *comment == '/' && *(comment + 1) == '/') + { + break; + } + comment++; + } + if (comment == cmd) + { // Comment at line beginning + continue; + } + else if (comment < stop) + { // Comment in middle of line + *comment = 0; + } + + AddCommandString (cmd); + } + } + ParsingKeyConf = false; +} + diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 0bdc622f..c8728515 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -70,7 +70,6 @@ CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) DMenu *DMenu::CurrentMenu; int DMenu::MenuTime; -FListMenuDescriptor *MainMenu; FGameStartup GameStartupInfo; EMenuState menuactive; bool M_DemoNoPlay; diff --git a/src/namedef.h b/src/namedef.h index 684d447f..d9573b74 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -280,6 +280,8 @@ xx(Communicator) // Textmap properties //xx(X) //xx(Y) +xx(ZFloor) +xx(ZCeiling) xx(Height) //xx(Tid) //xx(Angle) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 9b1119e0..39da6b65 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -145,6 +145,11 @@ void SetStrifeType(int convid, const PClass *Class) StrifeTypes[convid] = Class; } +void ClearStrifeTypes() +{ + StrifeTypes.Clear(); +} + void SetConversation(int convid, const PClass *Class, int dlgindex) { if (convid != -1) diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 7f385242..557928c5 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -638,14 +638,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec) void DAnimatedDoor::Serialize (FArchive &arc) { Super::Serialize (arc); - - FTextureID basetex; - if (arc.IsStoring()) - { - basetex = m_DoorAnim->BaseTexture; - } - arc << m_Line1 << m_Line2 << m_Frame << m_Timer @@ -653,20 +646,8 @@ void DAnimatedDoor::Serialize (FArchive &arc) << m_Status << m_Speed << m_Delay - << basetex; - if (SaveVersion < 2336) - { - m_SetBlocking1 = m_SetBlocking2 = true; - } - else - { - arc << m_SetBlocking1 << m_SetBlocking2; - } - - if (arc.IsLoading()) - { - m_DoorAnim = TexMan.FindAnimatedDoor (basetex); - } + << m_DoorAnim + << m_SetBlocking1 << m_SetBlocking2; } DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a7360089..0b13c8c7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -258,18 +258,9 @@ void AActor::Serialize (FArchive &arc) << args[0] << args[1] << args[2] << args[3] << args[4] << goal << waterlevel - << MinMissileChance; - if (SaveVersion >= 2826) - { - arc << SpawnFlags; - } - else - { - WORD w; - arc << w; - SpawnFlags = w; - } - arc << Inventory + << MinMissileChance + << SpawnFlags + << Inventory << InventoryID << id << FloatBobPhase @@ -281,12 +272,9 @@ void AActor::Serialize (FArchive &arc) << ActiveSound << UseSound << BounceSound - << WallBounceSound; - if (SaveVersion >= 2234) - { - arc << CrushPainSound; - } - arc << Speed + << WallBounceSound + << CrushPainSound + << Speed << FloatSpeed << Mass << PainChance @@ -313,83 +301,14 @@ void AActor::Serialize (FArchive &arc) << pushfactor << Species << Score - << Tag; - if (SaveVersion >= 1904) - { - arc << lastpush << lastbump; - } - - if (SaveVersion >= 1900) - { - arc << PainThreshold; - } - if (SaveVersion >= 1914) - { - arc << DamageFactor; - } - if (SaveVersion > 2036) - { - arc << WeaveIndexXY << WeaveIndexZ; - } - else - { - int index; - - if (SaveVersion < 2036) - { - index = special2; - } - else - { - arc << index; - } - // A_BishopMissileWeave and A_CStaffMissileSlither stored the weaveXY - // value in different parts of the index. - if (this->IsKindOf(PClass::FindClass("BishopFX"))) - { - WeaveIndexXY = index >> 16; - WeaveIndexZ = index; - } - else - { - WeaveIndexXY = index; - WeaveIndexZ = 0; - } - } - if (SaveVersion >= 2450) - { - arc << PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner; - arc << PoisonDamage << PoisonDuration << PoisonPeriod; - } - - // Skip past uservar array in old savegames - if (SaveVersion < 1933) - { - int foo; - for (int i = 0; i < 10; ++i) - arc << foo; - } - - if (SaveVersion > 2560) - { - arc << ConversationRoot << Conversation; - } - else // old code which uses relative indexing. - { - int convnum; - - convnum = arc.ReadCount(); - if (GetConversation(GetClass()->TypeName) == -1) - { - Conversation = NULL; - ConversationRoot = -1; - } - else - { - // This cannot be restored anymore. - I_Error("Cannot load old savegames with active dialogues"); - } - } + << Tag + << lastpush << lastbump + << PainThreshold + << DamageFactor + << WeaveIndexXY << WeaveIndexZ + << PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner + << PoisonDamage << PoisonDuration << PoisonPeriod + << ConversationRoot << Conversation; if (arc.IsLoading ()) { @@ -5667,12 +5586,13 @@ void FreeDropItemChain(FDropItem *chain) } } -FDropItemPtrArray::~FDropItemPtrArray() +void FDropItemPtrArray::Clear() { for (unsigned int i = 0; i < Size(); ++i) { FreeDropItemChain ((*this)[i]); } + TArray::Clear(); } int StoreDropItemChain(FDropItem *chain) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index a30e2d73..606acdb2 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -861,15 +861,7 @@ void P_MovePsprites (player_t *player) FArchive &operator<< (FArchive &arc, pspdef_t &def) { - arc << def.state << def.tics << def.sx << def.sy; - if (SaveVersion >= 2295) - { - arc << def.sprite << def.frame; - } - else - { - def.sprite = def.state->sprite; - def.frame = def.state->Frame; - } + arc << def.state << def.tics << def.sx << def.sy + << def.sprite << def.frame; return arc; } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index c3c7ee26..a8d01acf 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -347,16 +347,8 @@ void P_SerializeWorld (FArchive &arc) << sec->interpolations[0] << sec->interpolations[1] << sec->interpolations[2] - << sec->interpolations[3]; - - if (SaveVersion < 2492) - { - sec->SeqName = NAME_None; - } - else - { - arc << sec->SeqName; - } + << sec->interpolations[3] + << sec->SeqName; sec->e->Serialize(arc); if (arc.IsStoring ()) @@ -445,15 +437,7 @@ FArchive &operator<< (FArchive &arc, sector_t::splane &p) { arc << p.xform.xoffs << p.xform.yoffs << p.xform.xscale << p.xform.yscale << p.xform.angle << p.xform.base_yoffs << p.xform.base_angle - << p.Flags << p.Light << p.Texture << p.TexZ; - if (SaveVersion >= 2992) - { - arc << p.alpha; - } - else - { - p.alpha = FRACUNIT; - } + << p.Flags << p.Light << p.Texture << p.TexZ << p.alpha; return arc; } @@ -615,15 +599,6 @@ void P_SerializeSubsectors(FArchive &arc) } else { - if (SaveVersion < 2609) - { - if (hasglnodes) - { - RecalculateDrawnSubsectors(); - } - return; - } - arc << num_verts << num_subs << num_nodes; if (num_verts != numvertexes || num_subs != numsubsectors || diff --git a/src/p_setup.cpp b/src/p_setup.cpp index cb380784..15a39987 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -106,6 +106,8 @@ bool P_IsBuildMap(MapData *map); // int numvertexes; vertex_t* vertexes; +int numvertexdatas; +vertexdata_t* vertexdatas; int numsegs; seg_t* segs; @@ -795,6 +797,7 @@ void P_LoadVertexes (MapData * map) // Determine number of vertices: // total lump length / vertex record length. numvertexes = map->MapLumps[ML_VERTEXES].Size / sizeof(mapvertex_t); + numvertexdatas = 0; if (numvertexes == 0) { @@ -803,6 +806,7 @@ void P_LoadVertexes (MapData * map) // Allocate memory for buffer. vertexes = new vertex_t[numvertexes]; + vertexdatas = NULL; map->Seek(ML_VERTEXES); @@ -3533,6 +3537,7 @@ void P_FreeExtraLevelData() delete node; node = next; } + FBlockNode::FreeBlocks = NULL; } { msecnode_t *node = headsecnode; @@ -3571,8 +3576,11 @@ void P_SetupLevel (char *lumpname, int position) wminfo.partime = 180; + MapThingsConverted.Clear(); + linemap.Clear(); FCanvasTextureInfo::EmptyList (); R_FreePastViewers (); + P_ClearUDMFKeys(); if (!savegamerestore) { diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 3ebaef14..7cf6c5fb 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -309,6 +309,27 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt) mt->type = 0; } } + + for(int i = 0; i < numvertexdatas; i++) + { + if (vertexdatas[i].flags & VERTEXFLAG_ZCeilingEnabled) + { + vt_heights[1][i] = vertexdatas[i].zCeiling; + vt_found = true; + } + + if (vertexdatas[i].flags & VERTEXFLAG_ZFloorEnabled) + { + vt_heights[0][i] = vertexdatas[i].zFloor; + vt_found = true; + } + } + + // If vertexdata_t is ever extended for non-slope usage, this will obviously have to be deferred or removed. + delete[] vertexdatas; + vertexdatas = NULL; + numvertexdatas = 0; + if (vt_found) { for (int i = 0; i < numsectors; i++) diff --git a/src/p_states.cpp b/src/p_states.cpp index 15ff3711..21dd1537 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -861,7 +861,6 @@ bool FStateDefinitions::AddStates(FState *state, const char *framechars) int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults) { - static int c=0; int count = StateArray.Size(); if (count > 0) diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 622fd639..6e468e41 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -56,18 +56,19 @@ class DActiveButton : public DThinker DECLARE_CLASS (DActiveButton, DThinker) public: DActiveButton (); - DActiveButton (side_t *, int, WORD switchnum, fixed_t x, fixed_t y, bool flippable); + DActiveButton (side_t *, int, FSwitchDef *, fixed_t x, fixed_t y, bool flippable); void Serialize (FArchive &arc); void Tick (); - side_t *m_Side; - SBYTE m_Part; - WORD m_SwitchDef; - WORD m_Frame; - WORD m_Timer; - bool bFlippable; - fixed_t m_X, m_Y; // Location of timer sound + side_t *m_Side; + SBYTE m_Part; + bool bFlippable; + bool bReturning; + FSwitchDef *m_SwitchDef; + SDWORD m_Frame; + DWORD m_Timer; + fixed_t m_X, m_Y; // Location of timer sound protected: bool AdvanceFrame (); @@ -81,8 +82,7 @@ protected: // //========================================================================== -static bool P_StartButton (side_t *side, int Where, int switchnum, - fixed_t x, fixed_t y, bool useagain) +static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, fixed_t x, fixed_t y, bool useagain) { DActiveButton *button; TThinkerIterator iterator; @@ -97,7 +97,7 @@ static bool P_StartButton (side_t *side, int Where, int switchnum, } } - new DActiveButton (side, Where, switchnum, x, y, useagain); + new DActiveButton (side, Where, Switch, x, y, useagain); return true; } @@ -168,15 +168,15 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) if (open.range <= 0) goto onesided; - if ((TexMan.FindSwitch (side->GetTexture(side_t::top))) != -1) + if ((TexMan.FindSwitch (side->GetTexture(side_t::top))) != NULL) { return (user->z + user->height >= open.top); } - else if ((TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != -1) + else if ((TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != NULL) { return (user->z <= open.bottom); } - else if ((line->flags & (ML_3DMIDTEX)) || (TexMan.FindSwitch (side->GetTexture(side_t::mid))) != -1) + else if ((line->flags & (ML_3DMIDTEX)) || (TexMan.FindSwitch (side->GetTexture(side_t::mid))) != NULL) { // 3DMIDTEX lines will force a mid texture check if no switch is found on this line // to keep compatibility with Eternity's implementation. @@ -202,18 +202,17 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques { int texture; int sound; - int i; FSwitchDef *Switch; - if ((i = TexMan.FindSwitch (side->GetTexture(side_t::top))) != -1) + if ((Switch = TexMan.FindSwitch (side->GetTexture(side_t::top))) != NULL) { texture = side_t::top; } - else if ((i = TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != -1) + else if ((Switch = TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != NULL) { texture = side_t::bottom; } - else if ((i = TexMan.FindSwitch (side->GetTexture(side_t::mid))) != -1) + else if ((Switch = TexMan.FindSwitch (side->GetTexture(side_t::mid))) != NULL) { texture = side_t::mid; } @@ -225,7 +224,6 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques } return false; } - Switch = TexMan.GetSwitch(i); // EXIT SWITCH? if (Switch->Sound != 0) @@ -252,10 +250,10 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques pt[0] = line->v1->x + (line->dx >> 1); pt[1] = line->v1->y + (line->dy >> 1); - side->SetTexture(texture, Switch->u[0].Texture); + side->SetTexture(texture, Switch->frames[0].Texture); if (useAgain || Switch->NumFrames > 1) { - playsound = P_StartButton (side, texture, i, pt[0], pt[1], !!useAgain); + playsound = P_StartButton (side, texture, Switch, pt[0], pt[1], !!useAgain); } else { @@ -289,9 +287,11 @@ DActiveButton::DActiveButton () m_X = 0; m_Y = 0; bFlippable = false; + bReturning = false; + m_Frame = 0; } -DActiveButton::DActiveButton (side_t *side, int Where, WORD switchnum, +DActiveButton::DActiveButton (side_t *side, int Where, FSwitchDef *Switch, fixed_t x, fixed_t y, bool useagain) { m_Side = side; @@ -299,9 +299,10 @@ DActiveButton::DActiveButton (side_t *side, int Where, WORD switchnum, m_X = x; m_Y = y; bFlippable = useagain; + bReturning = false; - m_SwitchDef = switchnum; - m_Frame = 65535; + m_SwitchDef = Switch; + m_Frame = -1; AdvanceFrame (); } @@ -313,18 +314,8 @@ DActiveButton::DActiveButton (side_t *side, int Where, WORD switchnum, void DActiveButton::Serialize (FArchive &arc) { - SDWORD sidenum; - Super::Serialize (arc); - if (arc.IsStoring ()) - { - sidenum = m_Side ? SDWORD(m_Side - sides) : -1; - } - arc << sidenum << m_Part << m_SwitchDef << m_Frame << m_Timer << bFlippable << m_X << m_Y; - if (arc.IsLoading ()) - { - m_Side = sidenum >= 0 ? sides + sidenum : NULL; - } + arc << m_Side << m_Part << m_SwitchDef << m_Frame << m_Timer << bFlippable << m_X << m_Y << bReturning; } //========================================================================== @@ -335,16 +326,23 @@ void DActiveButton::Serialize (FArchive &arc) void DActiveButton::Tick () { + if (m_SwitchDef == NULL) + { + // We lost our definition due to a bad savegame. + Destroy(); + return; + } + + FSwitchDef *def = bReturning? m_SwitchDef->PairDef : m_SwitchDef; if (--m_Timer == 0) { - FSwitchDef *def = TexMan.GetSwitch(m_SwitchDef); if (m_Frame == def->NumFrames - 1) { - m_SwitchDef = def->PairIndex; - if (m_SwitchDef != 65535) + bReturning = true; + def = m_SwitchDef->PairDef; + if (def != NULL) { - def = TexMan.GetSwitch(def->PairIndex); - m_Frame = 65535; + m_Frame = -1; S_Sound (m_X, m_Y, 0, CHAN_VOICE|CHAN_LISTENERZ, def->Sound != 0 ? FSoundID(def->Sound) : FSoundID("switches/normbutn"), 1, ATTN_STATIC); @@ -358,7 +356,7 @@ void DActiveButton::Tick () } bool killme = AdvanceFrame (); - m_Side->SetTexture(m_Part, def->u[m_Frame].Texture); + m_Side->SetTexture(m_Part, def->frames[m_Frame].Texture); if (killme) { @@ -376,7 +374,7 @@ void DActiveButton::Tick () bool DActiveButton::AdvanceFrame () { bool ret = false; - FSwitchDef *def = TexMan.GetSwitch(m_SwitchDef); + FSwitchDef *def = bReturning? m_SwitchDef->PairDef : m_SwitchDef; if (++m_Frame == def->NumFrames - 1) { @@ -391,17 +389,10 @@ bool DActiveButton::AdvanceFrame () } else { - if (def->u[m_Frame].Time & 0xffff0000) + m_Timer = def->frames[m_Frame].TimeMin; + if (def->frames[m_Frame].TimeRnd != 0) { - int t = pr_switchanim(); - - m_Timer = (WORD)((((t | (pr_switchanim() << 8)) - % def->u[m_Frame].Time) >> 16) - + (def->u[m_Frame].Time & 0xffff)); - } - else - { - m_Timer = (WORD)def->u[m_Frame].Time; + m_Timer += pr_switchanim(def->frames[m_Frame].TimeRnd); } } return ret; diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index 14d2bb3d..c3df86b2 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -242,6 +242,8 @@ void P_InitTerrainTypes () int lump; int size; + Splashes.Clear(); + Terrains.Clear(); size = (TexMan.NumTextures()+1); TerrainTypes.Resize(size); TerrainTypes.Clear(); diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 0fba825b..72c3cb24 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -390,6 +390,7 @@ class UDMFParser : public UDMFParserBase TArray ParsedSideTextures; TArray ParsedSectors; TArray ParsedVertices; + TArray ParsedVertexDatas; FDynamicColormap *fogMap, *normMap; @@ -1303,9 +1304,10 @@ public: // //=========================================================================== - void ParseVertex(vertex_t *vt) + void ParseVertex(vertex_t *vt, vertexdata_t *vd) { vt->x = vt->y = 0; + vd->zCeiling = vd->zFloor = vd->flags = 0; sc.MustGetStringName("{"); while (!sc.CheckString("}")) { @@ -1320,9 +1322,21 @@ public: case NAME_X: vt->x = FLOAT2FIXED(strtod(value, NULL)); break; + case NAME_Y: vt->y = FLOAT2FIXED(strtod(value, NULL)); break; + + case NAME_ZCeiling: + vd->zCeiling = FLOAT2FIXED(strtod(value, NULL)); + vd->flags |= VERTEXFLAG_ZCeilingEnabled; + break; + + case NAME_ZFloor: + vd->zFloor = FLOAT2FIXED(strtod(value, NULL)); + vd->flags |= VERTEXFLAG_ZFloorEnabled; + break; + default: break; } @@ -1520,8 +1534,10 @@ public: else if (sc.Compare("vertex")) { vertex_t vt; - ParseVertex(&vt); + vertexdata_t vd; + ParseVertex(&vt, &vd); ParsedVertices.Push(vt); + ParsedVertexDatas.Push(vd); } else { @@ -1534,6 +1550,11 @@ public: vertexes = new vertex_t[numvertexes]; memcpy(vertexes, &ParsedVertices[0], numvertexes * sizeof(*vertexes)); + // Create the real vertex datas + numvertexdatas = ParsedVertexDatas.Size(); + vertexdatas = new vertexdata_t[numvertexdatas]; + memcpy(vertexdatas, &ParsedVertexDatas[0], numvertexdatas * sizeof(*vertexdatas)); + // Create the real sectors numsectors = ParsedSectors.Size(); sectors = new sector_t[numsectors]; diff --git a/src/p_user.cpp b/src/p_user.cpp index 836b665d..a9c04ad4 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -432,10 +432,6 @@ void APlayerPawn::Serialize (FArchive &arc) << MorphWeapon << DamageFade << PlayerFlags; - if (SaveVersion < 2435) - { - DamageFade.a = 255; - } } //=========================================================================== @@ -2554,33 +2550,9 @@ void player_t::Serialize (FArchive &arc) << poisoncount << poisoner << attacker - << extralight; - if (SaveVersion < 1858) - { - int fixedmap; - arc << fixedmap; - fixedcolormap = NOFIXEDCOLORMAP; - fixedlightlevel = -1; - if (fixedmap >= NUMCOLORMAPS) - { - fixedcolormap = fixedmap - NUMCOLORMAPS; - } - else if (fixedmap > 0) - { - fixedlightlevel = fixedmap; - } - } - else if (SaveVersion < 1893) - { - int ll; - arc << fixedcolormap << ll; - fixedlightlevel = ll; - } - else - { - arc << fixedcolormap << fixedlightlevel; - } - arc << morphTics + << extralight + << fixedcolormap << fixedlightlevel + << morphTics << MorphedPlayerClass << MorphStyle << MorphExitFlash diff --git a/src/r_defs.h b/src/r_defs.h index ab55f0de..b43c9c4b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -70,6 +70,16 @@ extern size_t MaxDrawSegs; // Note: transformed values not buffered locally, // like some DOOM-alikes ("wt", "WebView") did. // +enum +{ + VERTEXFLAG_ZCeilingEnabled = 0x01, + VERTEXFLAG_ZFloorEnabled = 0x02 +}; +struct vertexdata_t +{ + fixed_t zCeiling, zFloor; + DWORD flags; +}; struct vertex_t { fixed_t x, y; diff --git a/src/r_interpolate.cpp b/src/r_interpolate.cpp index f2fba2f8..f145347a 100644 --- a/src/r_interpolate.cpp +++ b/src/r_interpolate.cpp @@ -826,16 +826,7 @@ void DPolyobjInterpolation::Serialize(FArchive &arc) arc << po << oldverts; poly = polyobjs + po; - if (SaveVersion >= 2448) - { - arc << oldcx << oldcy; - } - else - { - // This will glitch if an old savegame is loaded but at least it'll allow loading it. - oldcx = poly->CenterSpot.x; - oldcy = poly->CenterSpot.y; - } + arc << oldcx << oldcy; if (arc.IsLoading()) bakverts.Resize(oldverts.Size()); } diff --git a/src/r_state.h b/src/r_state.h index 9044da72..65296838 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -55,6 +55,8 @@ extern DWORD NumStdSprites; extern int numvertexes; extern vertex_t* vertexes; +extern int numvertexdatas; +extern vertexdata_t* vertexdatas; extern int numsegs; extern seg_t* segs; diff --git a/src/r_things.cpp b/src/r_things.cpp index 4d40c04c..6fa35743 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2357,6 +2357,7 @@ void R_InitParticles () if ( NumParticles < 100 ) NumParticles = 100; + R_DeinitParticles(); Particles = new particle_t[NumParticles]; R_ClearParticles (); atterm (R_DeinitParticles); diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index c194d744..3245c20f 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -857,6 +857,8 @@ static void S_ClearSoundData() PlayerSounds.Clear(); DefPlayerClass = 0; DefPlayerClassName = ""; + MusicAliases.Clear(); + MidiDevices.Clear(); } //========================================================================== @@ -867,10 +869,11 @@ static void S_ClearSoundData() // Also registers Blood SFX files and Strife's voices. //========================================================================== -void S_ParseSndInfo () +void S_ParseSndInfo (bool redefine) { int lump; + if (!redefine) SavedPlayerSounds.Clear(); // clear skin sounds only for initial parsing. atterm (S_ClearSoundData); S_ClearSoundData(); // remove old sound data first! @@ -2016,10 +2019,6 @@ void AAmbientSound::Serialize (FArchive &arc) { Super::Serialize (arc); arc << bActive << NextCheck; - if (SaveVersion < 2798) - { - NextCheck += level.maptime; - } } //========================================================================== diff --git a/src/s_sound.cpp b/src/s_sound.cpp index bb85541c..c09e913b 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -322,7 +322,7 @@ void S_Init () void S_InitData () { LastLocalSndInfo = LastLocalSndSeq = ""; - S_ParseSndInfo (); + S_ParseSndInfo (false); S_ParseSndSeq (-1); S_ParseMusInfo(); } @@ -408,7 +408,7 @@ void S_Start () } // Parse the global SNDINFO - S_ParseSndInfo(); + S_ParseSndInfo(true); if (*LocalSndInfo) { diff --git a/src/s_sound.h b/src/s_sound.h index ee831bdd..12e7ee3c 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -331,7 +331,7 @@ void S_UpdateSounds (AActor *listener); void S_RestoreEvictedChannels(); // [RH] S_sfx "maintenance" routines -void S_ParseSndInfo (); +void S_ParseSndInfo (bool redefine); void S_ParseReverbDef (); void S_UnloadReverbDef (); diff --git a/src/statistics.cpp b/src/statistics.cpp index 276090eb..9c07ac6d 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -134,6 +134,7 @@ static void ParseStatistics(const char *fn, TArray &statlist) { FScanner sc; sc.OpenFile(fn); + statlist.Clear(); while (sc.GetString()) { diff --git a/src/svnrevision.h b/src/svnrevision.h index cb1b930b..9ef7adf0 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3029" -#define ZD_SVN_REVISION_NUMBER 3029 +#define ZD_SVN_REVISION_STRING "3038" +#define ZD_SVN_REVISION_NUMBER 3038 diff --git a/src/teaminfo.cpp b/src/teaminfo.cpp index c54b2f9d..f5c3c35e 100644 --- a/src/teaminfo.cpp +++ b/src/teaminfo.cpp @@ -131,6 +131,7 @@ void FTeam::ParseTeamInfo () { int iLump, iLastLump = 0; + Teams.Clear(); while ((iLump = Wads.FindLump ("TEAMINFO", &iLastLump)) != -1) { FScanner Scan (iLump); diff --git a/src/textures/anim_switches.cpp b/src/textures/anim_switches.cpp index cb1b5ae8..014e879f 100644 --- a/src/textures/anim_switches.cpp +++ b/src/textures/anim_switches.cpp @@ -63,8 +63,6 @@ void FTextureManager::InitSwitchList () { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; int lump = Wads.CheckNumForName ("SWITCHES"); - FSwitchDef **origMap; - int i, j; if (lump != -1) { @@ -87,46 +85,19 @@ void FTextureManager::InitSwitchList () { def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); - def1->PreTexture = def2->u[0].Texture = CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags); - def2->PreTexture = def1->u[0].Texture = CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags); + def1->PreTexture = def2->frames[0].Texture = CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags); + def2->PreTexture = def1->frames[0].Texture = CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags); def1->Sound = def2->Sound = 0; def1->NumFrames = def2->NumFrames = 1; - def1->u[0].Time = def2->u[0].Time = 0; - def2->PairIndex = AddSwitchDef (def1); - def1->PairIndex = AddSwitchDef (def2); + def1->frames[0].TimeMin = def2->frames[0].TimeMin = 0; + def1->frames[0].TimeRnd = def2->frames[0].TimeRnd = 0; + AddSwitchPair(def1, def2); } } } mSwitchDefs.ShrinkToFit (); - - // Sort mSwitchDefs for quick searching - origMap = new FSwitchDef *[mSwitchDefs.Size ()]; - for (i = 0; i < (int)mSwitchDefs.Size (); i++) - { - origMap[i] = mSwitchDefs[i]; - } - - qsort (&mSwitchDefs[0], i, sizeof(FSwitchDef *), SortSwitchDefs); - - // Correct the PairIndex of each switch def, since the sorting broke them - for (i = (int)(mSwitchDefs.Size () - 1); i >= 0; i--) - { - FSwitchDef *def = mSwitchDefs[i]; - if (def->PairIndex != 65535) - { - for (j = (int)(mSwitchDefs.Size () - 1); j >= 0; j--) - { - if (mSwitchDefs[j] == origMap[def->PairIndex]) - { - def->PairIndex = (WORD)j; - break; - } - } - } - } - - delete[] origMap; + qsort (&mSwitchDefs[0], mSwitchDefs.Size(), sizeof(FSwitchDef *), SortSwitchDefs); } //========================================================================== @@ -228,18 +199,18 @@ void FTextureManager::ProcessSwitchDef (FScanner &sc) def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); def2->Sound = def1->Sound; def2->NumFrames = 1; - def2->u[0].Time = 0; - def2->u[0].Texture = picnum; + def2->frames[0].TimeMin = 0; + def2->frames[0].TimeRnd = 0; + def2->frames[0].Texture = picnum; } def1->PreTexture = picnum; - def2->PreTexture = def1->u[def1->NumFrames-1].Texture; + def2->PreTexture = def1->frames[def1->NumFrames-1].Texture; if (def1->PreTexture == def2->PreTexture) { sc.ScriptError ("The on state for switch %s must end with a texture other than %s", picname.GetChars(), picname.GetChars()); } - def2->PairIndex = AddSwitchDef (def1); - def1->PairIndex = AddSwitchDef (def2); + AddSwitchPair(def1, def2); def1->QuestPanel = def2->QuestPanel = quest; } @@ -286,7 +257,8 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad) if (sc.Compare ("tics")) { sc.MustGetNumber (); - thisframe.Time = sc.Number & 65535; + thisframe.TimeMin = sc.Number & 65535; + thisframe.TimeRnd = 0; } else if (sc.Compare ("rand")) { @@ -300,11 +272,13 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad) { swapvalues (min, max); } - thisframe.Time = ((max - min + 1) << 16) | min; + thisframe.TimeMin = min; + thisframe.TimeRnd = (max - min + 1); } else { - thisframe.Time = 0; // Shush, GCC. + thisframe.TimeMin = 0; // Shush, GCC. + thisframe.TimeRnd = 0; sc.ScriptError ("Must specify a duration for switch frame"); } frames.Push(thisframe); @@ -324,11 +298,11 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad) return NULL; } - def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, u[0]) + frames.Size()*sizeof(frames[0])); + def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, frames[0]) + frames.Size()*sizeof(frames[0])); def->Sound = sound; def->NumFrames = frames.Size(); - memcpy (&def->u[0], &frames[0], frames.Size() * sizeof(frames[0])); - def->PairIndex = 65535; + memcpy (&def->frames[0], &frames[0], frames.Size() * sizeof(frames[0])); + def->PairDef = NULL; return def; } @@ -338,20 +312,54 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad) // //========================================================================== -WORD FTextureManager::AddSwitchDef (FSwitchDef *def) +void FTextureManager::AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2) { unsigned int i; + FSwitchDef *sw1 = NULL; + FSwitchDef *sw2 = NULL; + unsigned int index1 = 0xffffffff, index2 = 0xffffffff; for (i = mSwitchDefs.Size (); i-- > 0; ) { - if (mSwitchDefs[i]->PreTexture == def->PreTexture) + if (mSwitchDefs[i]->PreTexture == def1->PreTexture) { - M_Free (mSwitchDefs[i]); - mSwitchDefs[i] = def; - return (WORD)i; + index1 = i; + sw1 = mSwitchDefs[index1]; + if (index2 != 0xffffffff) break; + } + if (mSwitchDefs[i]->PreTexture == def2->PreTexture) + { + index2 = i; + sw2 = mSwitchDefs[index2]; + if (index1 != 0xffffffff) break; } } - return (WORD)mSwitchDefs.Push (def); + + def1->PairDef = def2; + def2->PairDef = def1; + + if (sw1 != NULL && sw2 != NULL && sw1->PairDef == sw2 && sw2->PairDef == sw1) + { + //We are replacing an existing pair so we can safely delete the old definitions + M_Free(sw1); + M_Free(sw2); + mSwitchDefs[index1] = def1; + mSwitchDefs[index2] = def2; + } + else + { + // This new switch will not or only partially replace an existing pair. + // We should not break up an old pair if the new one only redefined one + // of the two textures. These paired definitions will only be used + // as the return animation so their names don't matter. Better clear them to be safe. + if (sw1 != NULL) sw1->PreTexture.SetInvalid(); + if (sw2 != NULL) sw2->PreTexture.SetInvalid(); + sw1 = NULL; + sw2 = NULL; + unsigned int pos = mSwitchDefs.Reserve(2); + mSwitchDefs[pos] = def1; + mSwitchDefs[pos+1] = def2; + } } //========================================================================== @@ -360,7 +368,7 @@ WORD FTextureManager::AddSwitchDef (FSwitchDef *def) // //========================================================================== -int FTextureManager::FindSwitch (FTextureID texture) +FSwitchDef *FTextureManager::FindSwitch (FTextureID texture) { int mid, low, high; @@ -373,7 +381,7 @@ int FTextureManager::FindSwitch (FTextureID texture) mid = (high + low) / 2; if (mSwitchDefs[mid]->PreTexture == texture) { - return mid; + return mSwitchDefs[mid]; } else if (texture < mSwitchDefs[mid]->PreTexture) { @@ -385,6 +393,27 @@ int FTextureManager::FindSwitch (FTextureID texture) } } while (low <= high); } - return -1; + return NULL; +} + +//========================================================================== +// +// operator<< +// +//========================================================================== + +template<> FArchive &operator<< (FArchive &arc, FSwitchDef* &Switch) +{ + if (arc.IsStoring()) + { + arc << Switch->PreTexture; + } + else + { + FTextureID tex; + arc << tex; + Switch = TexMan.FindSwitch(tex); + } + return arc; } diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 3a75334a..65405e5c 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -903,3 +903,24 @@ void FTextureManager::UpdateAnimations (DWORD mstime) } } +//========================================================================== +// +// operator<< +// +//========================================================================== + +template<> FArchive &operator<< (FArchive &arc, FDoorAnimation* &Doorani) +{ + if (arc.IsStoring()) + { + arc << Doorani->BaseTexture; + } + else + { + FTextureID tex; + arc << tex; + Doorani = TexMan.FindAnimatedDoor(tex); + } + return arc; +} + diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index fc49d07d..72eb59f2 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -48,9 +48,6 @@ #include "cmdlib.h" #include "g_level.h" -extern void R_InitBuildTiles(); - - FTextureManager TexMan; //========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index 7efac519..2b62c386 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -108,15 +108,16 @@ struct FAnimDef struct FSwitchDef { FTextureID PreTexture; // texture to switch from - WORD PairIndex; // switch def to use to return to PreTexture + FSwitchDef *PairDef; // switch def to use to return to PreTexture WORD NumFrames; // # of animation frames - int Sound; // sound to play at start of animation. Changed to int to avoiud having to include s_sound here. bool QuestPanel; // Special texture for Strife mission + int Sound; // sound to play at start of animation. Changed to int to avoiud having to include s_sound here. struct frame // Array of times followed by array of textures { // actual length of each array is - DWORD Time; + WORD TimeMin; + WORD TimeRnd; FTextureID Texture; - } u[1]; + } frames[1]; }; struct FDoorAnimation @@ -464,12 +465,7 @@ public: void UpdateAnimations (DWORD mstime); int GuesstimateNumTextures (); - int FindSwitch (FTextureID texture); - FSwitchDef *GetSwitch (unsigned int index) - { - if (index < mSwitchDefs.Size()) return mSwitchDefs[index]; - else return NULL; - } + FSwitchDef *FindSwitch (FTextureID texture); FDoorAnimation *FindAnimatedDoor (FTextureID picnum); private: @@ -507,7 +503,7 @@ private: void InitSwitchList (); void ProcessSwitchDef (FScanner &sc); FSwitchDef *ParseSwitchDef (FScanner &sc, bool ignoreBad); - WORD AddSwitchDef (FSwitchDef *def); + void AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2); struct TextureHash { diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index 6362c62f..1b2f844b 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -337,6 +337,7 @@ void LoadActors () { int lastlump, lump; + DropItemList.Clear(); FScriptPosition::ResetErrorCounter(); InitThingdef(); lastlump = 0; diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 54de97aa..30c35a0a 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -584,6 +584,7 @@ void InitThingdef() } // Create a sorted list of properties + if (properties.Size() == 0) { FAutoSegIterator probe(GRegHead, GRegTail); @@ -596,6 +597,7 @@ void InitThingdef() } // Create a sorted list of native action functions + if (AFTable.Size() == 0) { FAutoSegIterator probe(ARegHead, ARegTail); @@ -608,6 +610,7 @@ void InitThingdef() } // Create a sorted list of native variables + if (variables.Size() == 0) { FAutoSegIterator probe(MRegHead, MRegTail); diff --git a/src/version.h b/src/version.h index 08cb9596..6677e016 100644 --- a/src/version.h +++ b/src/version.h @@ -77,7 +77,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 1848 +#define MINSAVEVER 3030 #if ZD_SVN_REVISION_NUMBER < MINSAVEVER // If we don't know the current revision write something very high to ensure that @@ -87,8 +87,11 @@ static inline const char *MakeSaveSig() { static char foo[] = { 'Z','D','O','O','M','S','A','V','E', +#if SAVEVER > 99999 + '0' + (SAVEVER / 100000), +#endif #if SAVEVER > 9999 - '0' + (SAVEVER / 10000), + '0' + ((SAVEVER / 10000) % 10), #endif #if SAVEVER > 999 '0' + ((SAVEVER / 1000) % 10), diff --git a/tools/zipdir/zipdir.c b/tools/zipdir/zipdir.c index 62c62a5a..ae4738b0 100644 --- a/tools/zipdir/zipdir.c +++ b/tools/zipdir/zipdir.c @@ -610,6 +610,7 @@ dir_tree_t *add_dirs(char **argv) { // Skip hidden directories. (Prevents SVN bookkeeping // info from being included.) + // [BL] Also skip backup files. fts_set(fts, ent, FTS_SKIP); } if (ent->fts_info == FTS_D && ent->fts_level == 0) @@ -628,6 +629,11 @@ dir_tree_t *add_dirs(char **argv) // We're only interested in remembering files. continue; } + else if(ent->fts_name[strlen(ent->fts_name)-1] == '~') + { + // Don't remember backup files. + continue; + } file = alloc_file_entry("", ent->fts_path, ent->fts_statp->st_mtime); if (file == NULL) { diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index a3de2d31..a833fb8b 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -736,6 +736,7 @@ OptionMenu "HUDOptions" Option "Display nametags", "displaynametags", "DisplayTagsTypes" Option "Nametag color", "nametagcolor", "TextColors", "displaynametags" Option "Stretch status bar", "st_scale", "OnOff" + Option "Use old ouch mug shot formula", "st_oldouch", "OnOff" } //------------------------------------------------------------------------------------------- From d2cef2f3bef348c9c5d707b56d8fec629718aabf Mon Sep 17 00:00:00 2001 From: gez Date: Wed, 15 Dec 2010 16:32:37 +0000 Subject: [PATCH 63/82] * Updated to ZDoom r3042: - Added a 'restart' CCMD that allows restarting the engine with different WADs being loaded without quitting first - Fixed handling of missing backgrounds for intermission text screens for real this time. - Added automap patch to mark trigger lines. - Fixed: The TouchedActors array in the Dehacked parser was not freed after parsing was done. - Initialize the alt HUD explicitly in D_DoomMain. - Don't let S_UnloadReverbDef leave a broken list of sound environments behind. - Added more code to explicitly delete data before initializing it. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1129 b0f79afe-0144-0410-b225-9a4edf0717df --- src/am_map.cpp | 27 +- src/c_cvars.cpp | 5 + src/c_cvars.h | 1 + src/d_dehacked.cpp | 2 + src/d_main.cpp | 580 ++++++++++++++---------- src/d_main.h | 6 + src/dobjtype.cpp | 20 + src/dobjtype.h | 1 + src/g_game.cpp | 1 + src/g_shared/sbar.h | 1 + src/g_shared/sbarinfo.cpp | 2 + src/g_shared/shared_hud.cpp | 3 - src/g_shared/shared_sbar.cpp | 18 + src/intermission/intermission.cpp | 7 +- src/intermission/intermission_parse.cpp | 11 +- src/keysections.cpp | 2 + src/m_argv.cpp | 20 + src/m_argv.h | 1 + src/menu/loadsavemenu.cpp | 22 +- src/menu/menu.h | 24 + src/menu/menudef.cpp | 24 +- src/p_setup.cpp | 7 +- src/p_user.cpp | 1 + src/r_data.cpp | 33 +- src/r_things.cpp | 3 + src/r_translate.cpp | 2 + src/s_environment.cpp | 7 + src/s_sndseq.cpp | 27 +- src/s_sound.cpp | 1 + src/st_start.h | 12 +- src/statistics.cpp | 2 +- src/svnrevision.h | 4 +- src/thingdef/thingdef.cpp | 2 + src/thingdef/thingdef.h | 3 +- src/thingdef/thingdef_expression.cpp | 3 +- src/v_font.cpp | 15 + src/v_font.h | 3 +- src/v_palette.cpp | 2 + src/v_video.cpp | 64 +-- src/v_video.h | 2 +- src/xlat/parse_xlat.cpp | 17 +- wadsrc/static/menudef.txt | 3 + 42 files changed, 665 insertions(+), 326 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 5eb759ee..7c709019 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -91,7 +91,7 @@ struct AMColor static AMColor Background, YourColor, WallColor, TSWallColor, FDWallColor, CDWallColor, ThingColor, ThingColor_Item, ThingColor_CountItem, ThingColor_Monster, ThingColor_Friend, - SecretWallColor, GridColor, XHairColor, + SpecialWallColor, SecretWallColor, GridColor, XHairColor, NotSeenColor, LockedColor, AlmostBackground, @@ -167,6 +167,7 @@ CVAR (Color, am_backcolor, 0x6c5440, CVAR_ARCHIVE); CVAR (Color, am_yourcolor, 0xfce8d8, CVAR_ARCHIVE); CVAR (Color, am_wallcolor, 0x2c1808, CVAR_ARCHIVE); CVAR (Color, am_secretwallcolor, 0x000000, CVAR_ARCHIVE); +CVAR (Color, am_specialwallcolor, 0xffffff, CVAR_ARCHIVE); CVAR (Color, am_tswallcolor, 0x888888, CVAR_ARCHIVE); CVAR (Color, am_fdwallcolor, 0x887058, CVAR_ARCHIVE); CVAR (Color, am_cdwallcolor, 0x4c3820, CVAR_ARCHIVE); @@ -177,6 +178,7 @@ CVAR (Color, am_notseencolor, 0x6c6c6c, CVAR_ARCHIVE); CVAR (Color, am_lockedcolor, 0x007800, CVAR_ARCHIVE); CVAR (Color, am_ovyourcolor, 0xfce8d8, CVAR_ARCHIVE); CVAR (Color, am_ovwallcolor, 0x00ff00, CVAR_ARCHIVE); +CVAR (Color, am_ovspecialwallcolor, 0xffffff, CVAR_ARCHIVE); CVAR (Color, am_ovthingcolor, 0xe88800, CVAR_ARCHIVE); CVAR (Color, am_ovotherwallscolor, 0x008844, CVAR_ARCHIVE); CVAR (Color, am_ovunseencolor, 0x00226e, CVAR_ARCHIVE); @@ -188,6 +190,7 @@ CVAR (Color, am_ovsecretsectorcolor,0x00ffff, CVAR_ARCHIVE); CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE); CVAR (Bool, am_drawmapback, true, CVAR_ARCHIVE); CVAR (Bool, am_showkeys, true, CVAR_ARCHIVE); +CVAR (Bool, am_showtriggerlines, false, CVAR_ARCHIVE); CVAR (Color, am_thingcolor_friend, 0xfcfcfc, CVAR_ARCHIVE); CVAR (Color, am_thingcolor_monster, 0xfcfcfc, CVAR_ARCHIVE); CVAR (Color, am_thingcolor_item, 0xfcfcfc, CVAR_ARCHIVE); @@ -897,6 +900,7 @@ static void AM_initColors (bool overlayed) { YourColor.FromCVar (am_ovyourcolor); WallColor.FromCVar (am_ovwallcolor); + SpecialWallColor.FromCVar(am_ovspecialwallcolor); SecretWallColor = WallColor; SecretSectorColor.FromCVar (am_ovsecretsectorcolor); ThingColor_Item.FromCVar (am_ovthingcolor_item); @@ -919,6 +923,7 @@ static void AM_initColors (bool overlayed) Background.FromCVar (am_backcolor); YourColor.FromCVar (am_yourcolor); SecretWallColor.FromCVar (am_secretwallcolor); + SpecialWallColor.FromCVar (am_specialwallcolor); WallColor.FromCVar (am_wallcolor); TSWallColor.FromCVar (am_tswallcolor); FDWallColor.FromCVar (am_fdwallcolor); @@ -960,6 +965,7 @@ static void AM_initColors (bool overlayed) AlmostBackground = DoomColors[2]; SecretSectorColor = SecretWallColor = + SpecialWallColor = WallColor = DoomColors[3]; TSWallColor = DoomColors[4]; FDWallColor = DoomColors[5]; @@ -981,6 +987,7 @@ static void AM_initColors (bool overlayed) AlmostBackground = DoomColors[2]; SecretSectorColor = SecretWallColor = + SpecialWallColor = WallColor = StrifeColors[3]; TSWallColor = StrifeColors[4]; FDWallColor = StrifeColors[5]; @@ -1002,6 +1009,7 @@ static void AM_initColors (bool overlayed) AlmostBackground = DoomColors[2]; SecretSectorColor = SecretWallColor = + SpecialWallColor = WallColor = RavenColors[3]; TSWallColor = RavenColors[4]; FDWallColor = RavenColors[5]; @@ -1836,14 +1844,16 @@ void AM_drawWalls (bool allmap) else if (lines[i].special == Door_LockedRaise || lines[i].special == ACS_LockedExecute || lines[i].special == ACS_LockedExecuteDoor || - (lines[i].special == Generic_Door && lines[i].args[4] !=0 )) + (lines[i].special == Door_Animated && lines[i].args[3] != 0) || + (lines[i].special == Generic_Door && lines[i].args[4] != 0)) { if (am_colorset == 0 || am_colorset == 3) // Raven games show door colors { int P_GetMapColorForLock(int lock); int lock; - if (lines[i].special==Door_LockedRaise) lock=lines[i].args[3]; + if (lines[i].special==Door_LockedRaise || lines[i].special==Door_Animated) + lock=lines[i].args[3]; else lock=lines[i].args[4]; int color = P_GetMapColorForLock(lock); @@ -1860,6 +1870,17 @@ void AM_drawWalls (bool allmap) AM_drawMline (&l, LockedColor); // locked special } } + else if (am_showtriggerlines && am_colorset == 0 && lines[i].special != 0 + && lines[i].special != Door_Open + && lines[i].special != Door_Close + && lines[i].special != Door_CloseWaitOpen + && lines[i].special != Door_Raise + && lines[i].special != Door_Animated + && lines[i].special != Generic_Door + && (lines[i].activation & SPAC_PlayerActivate)) + { + AM_drawMline(&l, SpecialWallColor); // wall with special non-door action the player can do + } else if (lines[i].backsector == NULL) { AM_drawMline(&l, WallColor); // one-sided wall diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 7b538763..3afdb7c8 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -600,6 +600,11 @@ void FBaseCVar::EnableCallbacks () } } +void FBaseCVar::DisableCallbacks () +{ + m_UseCallback = false; +} + // // Boolean cvar implementation // diff --git a/src/c_cvars.h b/src/c_cvars.h index 3b685948..d0ac84fe 100644 --- a/src/c_cvars.h +++ b/src/c_cvars.h @@ -117,6 +117,7 @@ public: static void EnableNoSet (); // enable the honoring of CVAR_NOSET static void EnableCallbacks (); + static void DisableCallbacks (); static void ResetColors (); // recalc color cvars' indices after screen change static void ListVars (const char *filter, bool plain); diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 225f24ca..e5fd308b 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2880,6 +2880,8 @@ void FinishDehPatch () // Now that all Dehacked patches have been processed, it's okay to free StateMap. StateMap.Clear(); StateMap.ShrinkToFit(); + TouchedActors.Clear(); + TouchedActors.ShrinkToFit(); } void ModifyDropAmount(AInventory *inv, int dropamount); diff --git a/src/d_main.cpp b/src/d_main.cpp index 2eaabf76..64cfd94a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -122,6 +122,7 @@ extern void M_SetDefaultMode (); extern void R_ExecuteSetViewSize (); extern void G_NewInit (); extern void SetupPlayerClasses (); +extern void HUD_InitHud(); const FIWADInfo *D_FindIWAD(TArray &wadfiles, const char *iwad, const char *basewad); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -222,6 +223,8 @@ FTexture *Page; FTexture *Advisory; bool nospriterename; FStartupInfo DoomStartupInfo; +FString lastIWAD; +int restart = 0; cycle_t FrameCycles; @@ -889,7 +892,7 @@ void D_Display () // // D_ErrorCleanup () // -// Cleanup after a recoverable error. +// Cleanup after a recoverable error or a restart //========================================================================== void D_ErrorCleanup () @@ -2024,269 +2027,368 @@ void D_DoomMain (void) } FString basewad = wad; - // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before - // the IWAD is known. - GetCmdLineFiles(pwads); - FString iwad = CheckGameInfo(pwads); + // reinit from here - FIWadManager *iwad_man = new FIWadManager; - const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); - gameinfo.gametype = iwad_info->gametype; - gameinfo.flags = iwad_info->flags; - gameinfo.ConfigName = iwad_info->Configname; - - GameConfig->DoGameSetup (gameinfo.ConfigName); - - AddAutoloadFiles(iwad_info->Autoname); - - // Run automatically executed files - execFiles = new DArgs; - GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName); - D_MultiExec (execFiles, true); - - // Run .cfg files at the start of the command line. - execFiles = Args->GatherFiles ("-exec"); - D_MultiExec (execFiles, true); - - C_ExecCmdLineParams (); // [RH] do all +set commands on the command line - - CopyFiles(allwads, pwads); - - // Since this function will never leave we must delete this array here manually. - pwads.Clear(); - pwads.ShrinkToFit(); - - Printf ("W_Init: Init WADfiles.\n"); - Wads.InitMultipleFiles (allwads); - allwads.Clear(); - allwads.ShrinkToFit(); - SetMapxxFlag(); - - // [RH] Initialize localizable strings. - GStrings.LoadStrings (false); - - V_InitFontColors (); - - // [RH] Moved these up here so that we can do most of our - // startup output in a fullscreen console. - - CT_Init (); - - Printf ("I_Init: Setting up machine state.\n"); - I_Init (); - - Printf ("V_Init: allocate screen.\n"); - V_Init (); - - // Base systems have been inited; enable cvar callbacks - FBaseCVar::EnableCallbacks (); - - Printf ("S_Init: Setting up sound.\n"); - S_Init (); - - Printf ("ST_Init: Init startup screen.\n"); - StartScreen = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5); - - ParseCompatibility(); - - CheckCmdLine(); - - // [RH] Load sound environments - S_ParseReverbDef (); - - // [RH] Parse through all loaded mapinfo lumps - Printf ("G_ParseMapInfo: Load map definitions.\n"); - G_ParseMapInfo (iwad_info->MapInfo); - ReadStatistics(); - - // [RH] Parse any SNDINFO lumps - Printf ("S_InitData: Load sound definitions.\n"); - S_InitData (); - - Printf ("Texman.Init: Init texture manager.\n"); - TexMan.Init(); - C_InitConback(); - - // [CW] Parse any TEAMINFO lumps. - Printf ("ParseTeamInfo: Load team definitions.\n"); - TeamLibrary.ParseTeamInfo (); - - FActorInfo::StaticInit (); - - // [GRB] Initialize player class list - SetupPlayerClasses (); - - - // [RH] Load custom key and weapon settings from WADs - D_LoadWadSettings (); - - // [GRB] Check if someone used clearplayerclasses but not addplayerclass - if (PlayerClasses.Size () == 0) + do { - I_FatalError ("No player classes defined"); - } - - StartScreen->Progress (); - - Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars()); - StartScreen->LoadingStatus ("Loading graphics", 0x3f); - R_Init (); - - Printf ("DecalLibrary: Load decals.\n"); - DecalLibrary.Clear (); - DecalLibrary.ReadAllDecals (); - - // [RH] Add any .deh and .bex files on the command line. - // If there are none, try adding any in the config file. - // Note that the command line overrides defaults from the config. - - if ((ConsiderPatches("-deh") | ConsiderPatches("-bex")) == 0 && - gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked")) - { - const char *key; - const char *value; - - while (GameConfig->NextInSection (key, value)) + if (restart) { - if (stricmp (key, "Path") == 0 && FileExists (value)) - { - Printf ("Applying patch %s\n", value); - D_LoadDehFile(value); - } + C_InitConsole(SCREENWIDTH, SCREENHEIGHT, false); } - } + nospriterename = false; - // Load embedded Dehacked patches - D_LoadDehLumps(); + // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before + // the IWAD is known. - // Create replacements for dehacked pickups - FinishDehPatch(); + GetCmdLineFiles(pwads); + FString iwad = CheckGameInfo(pwads); - FActorInfo::StaticSetActorNums (); + // The IWAD selection dialogue dpes not show in fullscreen so if the + // restart is initiated without a defined IWAD assume for now that it's not going to change. + if (iwad.Len() == 0) iwad = lastIWAD; - //Added by MC: - bglobal.getspawned.Clear(); - argcount = Args->CheckParmList("-bots", &args); - for (p = 0; p < argcount; ++p) - { - bglobal.getspawned.Push(args[p]); - } - bglobal.spawn_tries = 0; - bglobal.wanted_botnum = bglobal.getspawned.Size(); + FIWadManager *iwad_man = new FIWadManager; + const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); + gameinfo.gametype = iwad_info->gametype; + gameinfo.flags = iwad_info->flags; + gameinfo.ConfigName = iwad_info->Configname; + lastIWAD = iwad; - Printf ("M_Init: Init menus.\n"); - M_Init (); + FBaseCVar::DisableCallbacks(); + GameConfig->DoGameSetup (gameinfo.ConfigName); - Printf ("P_Init: Init Playloop state.\n"); - StartScreen->LoadingStatus ("Init game engine", 0x3f); - AM_StaticInit(); - P_Init (); + AddAutoloadFiles(iwad_info->Autoname); - P_SetupWeapons_ntohton(); + // Run automatically executed files + execFiles = new DArgs; + GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName); + D_MultiExec (execFiles, true); - //SBarInfo support. - SBarInfo::Load(); + // Run .cfg files at the start of the command line. + execFiles = Args->GatherFiles ("-exec"); + D_MultiExec (execFiles, true); - // [RH] User-configurable startup strings. Because BOOM does. - static const char *startupString[5] = { - "STARTUP1", "STARTUP2", "STARTUP3", "STARTUP4", "STARTUP5" - }; - for (p = 0; p < 5; ++p) - { - const char *str = GStrings[startupString[p]]; - if (str != NULL && str[0] != '\0') - { - Printf ("%s\n", str); - } - } + C_ExecCmdLineParams (); // [RH] do all +set commands on the command line - Printf ("D_CheckNetGame: Checking network game status.\n"); - StartScreen->LoadingStatus ("Checking network game status.", 0x3f); - D_CheckNetGame (); + CopyFiles(allwads, pwads); - // [RH] Lock any cvars that should be locked now that we're - // about to begin the game. - FBaseCVar::EnableNoSet (); + // Since this function will never leave we must delete this array here manually. + pwads.Clear(); + pwads.ShrinkToFit(); - delete iwad_man; // now we won't need this anymore - - // [RH] Run any saved commands from the command line or autoexec.cfg now. - gamestate = GS_FULLCONSOLE; - Net_NewMakeTic (); - DThinker::RunThinkers (); - gamestate = GS_STARTUP; - - // start the apropriate game based on parms - v = Args->CheckValue ("-record"); - - if (v) - { - G_RecordDemo (v); - autostart = true; - } - - delete StartScreen; - StartScreen = NULL; - - if (Args->CheckParm("-norun")) - { - throw CNoRunExit(); - } - - V_Init2(); - - v = Args->CheckValue("-playdemo"); - if (v != NULL) - { - singledemo = true; // quit after one demo - G_DeferedPlayDemo (v); - D_DoomLoop (); // never returns - } - - v = Args->CheckValue ("-timedemo"); - if (v) - { - G_TimeDemo (v); - D_DoomLoop (); // never returns - } + Printf ("W_Init: Init WADfiles.\n"); + Wads.InitMultipleFiles (allwads); + allwads.Clear(); + allwads.ShrinkToFit(); + SetMapxxFlag(); - v = Args->CheckValue ("-loadgame"); - if (v) - { - FString file(v); - FixPathSeperator (file); - DefaultExtension (file, ".zds"); - G_LoadGame (file); - } + // [RH] Initialize localizable strings. + GStrings.LoadStrings (false); - if (gameaction != ga_loadgame) - { - if (autostart || netgame) + V_InitFontColors (); + + // [RH] Moved these up here so that we can do most of our + // startup output in a fullscreen console. + + CT_Init (); + + if (!restart) { - // Do not do any screenwipes when autostarting a game. - if (!Args->CheckParm("-warpwipe")) + Printf ("I_Init: Setting up machine state.\n"); + I_Init (); + } + + Printf ("V_Init: allocate screen.\n"); + V_Init (!!restart); + + // Base systems have been inited; enable cvar callbacks + FBaseCVar::EnableCallbacks (); + + Printf ("S_Init: Setting up sound.\n"); + S_Init (); + + Printf ("ST_Init: Init startup screen.\n"); + if (!restart) StartScreen = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5); + else StartScreen = new FStartupScreen(0); + + ParseCompatibility(); + + CheckCmdLine(); + + // [RH] Load sound environments + S_ParseReverbDef (); + + // [RH] Parse through all loaded mapinfo lumps + Printf ("G_ParseMapInfo: Load map definitions.\n"); + G_ParseMapInfo (iwad_info->MapInfo); + ReadStatistics(); + + // [RH] Parse any SNDINFO lumps + Printf ("S_InitData: Load sound definitions.\n"); + S_InitData (); + + Printf ("Texman.Init: Init texture manager.\n"); + TexMan.Init(); + C_InitConback(); + + // [CW] Parse any TEAMINFO lumps. + Printf ("ParseTeamInfo: Load team definitions.\n"); + TeamLibrary.ParseTeamInfo (); + + FActorInfo::StaticInit (); + + // [GRB] Initialize player class list + SetupPlayerClasses (); + + + // [RH] Load custom key and weapon settings from WADs + D_LoadWadSettings (); + + // [GRB] Check if someone used clearplayerclasses but not addplayerclass + if (PlayerClasses.Size () == 0) + { + I_FatalError ("No player classes defined"); + } + + StartScreen->Progress (); + + Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars()); + StartScreen->LoadingStatus ("Loading graphics", 0x3f); + R_Init (); + + Printf ("DecalLibrary: Load decals.\n"); + DecalLibrary.ReadAllDecals (); + + // [RH] Add any .deh and .bex files on the command line. + // If there are none, try adding any in the config file. + // Note that the command line overrides defaults from the config. + + if ((ConsiderPatches("-deh") | ConsiderPatches("-bex")) == 0 && + gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked")) + { + const char *key; + const char *value; + + while (GameConfig->NextInSection (key, value)) { - NoWipe = TICRATE; + if (stricmp (key, "Path") == 0 && FileExists (value)) + { + Printf ("Applying patch %s\n", value); + D_LoadDehFile(value); + } } - CheckWarpTransMap (startmap, true); - if (demorecording) - G_BeginRecording (startmap); - G_InitNew (startmap, false); + } + + // Load embedded Dehacked patches + D_LoadDehLumps(); + + // Create replacements for dehacked pickups + FinishDehPatch(); + + FActorInfo::StaticSetActorNums (); + + //Added by MC: + bglobal.getspawned.Clear(); + argcount = Args->CheckParmList("-bots", &args); + for (p = 0; p < argcount; ++p) + { + bglobal.getspawned.Push(args[p]); + } + bglobal.spawn_tries = 0; + bglobal.wanted_botnum = bglobal.getspawned.Size(); + + Printf ("M_Init: Init menus.\n"); + M_Init (); + + Printf ("P_Init: Init Playloop state.\n"); + StartScreen->LoadingStatus ("Init game engine", 0x3f); + AM_StaticInit(); + P_Init (); + + P_SetupWeapons_ntohton(); + + //SBarInfo support. + SBarInfo::Load(); + HUD_InitHud(); + + // [RH] User-configurable startup strings. Because BOOM does. + static const char *startupString[5] = { + "STARTUP1", "STARTUP2", "STARTUP3", "STARTUP4", "STARTUP5" + }; + for (p = 0; p < 5; ++p) + { + const char *str = GStrings[startupString[p]]; + if (str != NULL && str[0] != '\0') + { + Printf ("%s\n", str); + } + } + + if (!restart) + { + Printf ("D_CheckNetGame: Checking network game status.\n"); + StartScreen->LoadingStatus ("Checking network game status.", 0x3f); + D_CheckNetGame (); + } + + // [RH] Lock any cvars that should be locked now that we're + // about to begin the game. + FBaseCVar::EnableNoSet (); + + delete iwad_man; // now we won't need this anymore + + // [RH] Run any saved commands from the command line or autoexec.cfg now. + gamestate = GS_FULLCONSOLE; + Net_NewMakeTic (); + DThinker::RunThinkers (); + gamestate = GS_STARTUP; + + if (!restart) + { + // start the apropriate game based on parms + v = Args->CheckValue ("-record"); + + if (v) + { + G_RecordDemo (v); + autostart = true; + } + + delete StartScreen; + StartScreen = NULL; + + if (Args->CheckParm("-norun")) + { + throw CNoRunExit(); + } + + V_Init2(); + + v = Args->CheckValue("-playdemo"); + if (v != NULL) + { + singledemo = true; // quit after one demo + G_DeferedPlayDemo (v); + D_DoomLoop (); // never returns + } + + v = Args->CheckValue ("-timedemo"); + if (v) + { + G_TimeDemo (v); + D_DoomLoop (); // never returns + } + + v = Args->CheckValue ("-loadgame"); + if (v) + { + FString file(v); + FixPathSeperator (file); + DefaultExtension (file, ".zds"); + G_LoadGame (file); + } + + if (gameaction != ga_loadgame) + { + if (autostart || netgame) + { + // Do not do any screenwipes when autostarting a game. + if (!Args->CheckParm("-warpwipe")) + { + NoWipe = TICRATE; + } + CheckWarpTransMap (startmap, true); + if (demorecording) + G_BeginRecording (startmap); + G_InitNew (startmap, false); + } + else + { + D_StartTitle (); // start up intro loop + } + } + else if (demorecording) + { + G_BeginRecording (NULL); + } + + atterm (D_QuitNetGame); // killough } else { + // These calls from inside V_Init2 are still necessary + C_NewModeAdjust(); + M_InitVideoModesMenu(); D_StartTitle (); // start up intro loop + setmodeneeded = false; // This may be set to true here, but isn't needed for a restart + } + + try + { + D_DoomLoop (); // never returns + } + catch (CRestartException &ex) + { + // Music and sound should be stopped first + S_StopMusic(true); + S_StopAllChannels (); + + // clean up game state + ST_Clear(); + D_ErrorCleanup (); + P_FreeLevelData(); + P_FreeExtraLevelData(); + + M_SaveDefaults(NULL); // save config before the restart + + // delete all data that cannot be left until reinitialization + V_ClearFonts(); // must clear global font pointers + R_DeinitTranslationTables(); // some tables are initialized from outside the translation code. + gameinfo.~gameinfo_t(); + new (&gameinfo) gameinfo_t; // Reset gameinfo + S_Shutdown(); // free all channels and delete playlist + C_ClearAliases(); // CCMDs won't be reinitialized so these need to be deleted here + + GC::FullGC(); // perform one final garbage collection before deleting the class data + PClass::ClearRuntimeData(); // clear all runtime generated class data + restart++; } } - else if (demorecording) - { - G_BeginRecording (NULL); - } - - atterm (D_QuitNetGame); // killough + while (1); +} - D_DoomLoop (); // never returns +//========================================================================== +// +// restart the game +// +//========================================================================== + +CCMD(restart) +{ + // remove command line args that would get in the way during restart + Args->RemoveArgs("-iwad"); + Args->RemoveArgs("-deh"); + Args->RemoveArgs("-bex"); + Args->RemoveArgs("-playdemo"); + Args->RemoveArgs("-file"); + Args->RemoveArgs("-altdeath"); + Args->RemoveArgs("-deathmatch"); + Args->RemoveArgs("-skill"); + Args->RemoveArgs("-savedir"); + Args->RemoveArgs("-xlat"); + Args->RemoveArgs("-oldsprites"); + + if (argv.argc() > 1) + { + for(int i=1;iAppendArg(argv[i]); + } + } + + // initiate the restart + throw CRestartException(); } //========================================================================== @@ -2336,6 +2438,14 @@ void FStartupScreen::AppendStatusLine(const char *status) { } + +void FStartupScreen::Progress(void) {} +void FStartupScreen::NetInit(char const *,int) {} +void FStartupScreen::NetProgress(int) {} +void FStartupScreen::NetMessage(char const *,...) {} +void FStartupScreen::NetDone(void) {} +bool FStartupScreen::NetLoop(bool (*)(void *),void *) { return false; } + //========================================================================== // // STAT fps diff --git a/src/d_main.h b/src/d_main.h index 415a6b94..7dd75a10 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -36,6 +36,12 @@ struct event_t; // calls all startup code, parses command line options. // If not overrided by user input, calls N_AdvanceDemo. // + +struct CRestartException +{ + char dummy; +}; + void D_DoomMain (void); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index f232d81f..03a8d2de 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -80,6 +80,24 @@ void PClass::StaticInit () } } +void PClass::ClearRuntimeData () +{ + StaticShutdown(); + + m_RuntimeActors.Clear(); + m_Types.Clear(); + memset(TypeHash, 0, sizeof(TypeHash)); + bShutdown = false; + + // Immediately reinitialize the internal classes + FAutoSegIterator probe(CRegHead, CRegTail); + + while (*++probe != NULL) + { + ((ClassReg *)*probe)->RegisterClass (); + } +} + void PClass::StaticShutdown () { TArray uniqueFPs(64); @@ -105,6 +123,8 @@ void PClass::StaticShutdown () uniqueFPs.Push(const_cast(type->FlatPointers)); } } + type->FlatPointers = NULL; + // For runtime classes, this call will also delete the PClass. PClass::StaticFreeData (type); } diff --git a/src/dobjtype.h b/src/dobjtype.h index e0192990..256e52ad 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -125,6 +125,7 @@ struct PClass static void StaticInit (); static void StaticShutdown (); static void StaticFreeData (PClass *type); + static void ClearRuntimeData(); // Per-class information ------------------------------------- FName TypeName; // this class's name diff --git a/src/g_game.cpp b/src/g_game.cpp index e10936f9..85bc45fc 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2573,6 +2573,7 @@ bool G_CheckDemoStatus (void) C_RestoreCVars (); // [RH] Restore cvars demo might have changed M_Free (demobuffer); + demobuffer = NULL; P_SetupWeapons_ntohton(); demoplayback = false; diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index b2f6173b..71dc6667 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -383,6 +383,7 @@ DBaseStatusBar *CreateCustomStatusBar(int script=0); void ST_FormatMapName(FString &mapname, const char *mapnamecolor = ""); void ST_LoadCrosshair(bool alwaysload=false); +void ST_Clear(); extern FTexture *CrosshairImage; #endif /* __SBAR_H__ */ diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index ee29a3b5..a552a3ad 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -423,6 +423,8 @@ static void FreeSBarInfoScript() void SBarInfo::Load() { + FreeSBarInfoScript(); + MugShotStates.Clear(); if(gameinfo.statusbar.IsNotEmpty()) { int lump = Wads.CheckNumForFullName(gameinfo.statusbar, true); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index d766d890..9901c794 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -769,14 +769,11 @@ static void DrawCoordinates(player_t * CPlayer) // draw the overlay // //--------------------------------------------------------------------------- -void HUD_InitHud(); void DrawHUD() { player_t * CPlayer = StatusBar->CPlayer; - if (HudFont==NULL) HUD_InitHud(); - players[consoleplayer].inventorytics = 0; if (hud_althudscale && SCREENWIDTH>640) { diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 75084ae3..3091d63e 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -197,6 +197,23 @@ void ST_LoadCrosshair(bool alwaysload) CrosshairImage = TexMan[TexMan.CheckForTexture(name, FTexture::TEX_MiscPatch)]; } +//--------------------------------------------------------------------------- +// +// ST_Clear +// +//--------------------------------------------------------------------------- + +void ST_Clear() +{ + if (StatusBar != NULL) + { + StatusBar->Destroy(); + StatusBar = NULL; + } + CrosshairImage = NULL; + CrosshairNum = 0; +} + //--------------------------------------------------------------------------- // // Constructor @@ -236,6 +253,7 @@ void DBaseStatusBar::Destroy () msg->Destroy(); msg = next; } + Messages = NULL; Super::Destroy(); } diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 1287f93c..0c75575c 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -110,8 +110,11 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) { texname = GStrings[texname+1]; } - mBackground = TexMan.CheckForTexture(texname, FTexture::TEX_MiscPatch); - mFlatfill = desc->mFlatfill; + if (texname[0] != 0) + { + mBackground = TexMan.CheckForTexture(texname, FTexture::TEX_MiscPatch); + mFlatfill = desc->mFlatfill; + } S_Sound (CHAN_VOICE | CHAN_UI, desc->mSound, 1.0f, ATTN_NONE); if (desc->mPalette.IsNotEmpty() && (lumpnum = Wads.CheckNumForFullName(desc->mPalette, true)) > 0) { diff --git a/src/intermission/intermission_parse.cpp b/src/intermission/intermission_parse.cpp index bf6ae0dd..fab4dca2 100644 --- a/src/intermission/intermission_parse.cpp +++ b/src/intermission/intermission_parse.cpp @@ -58,6 +58,7 @@ void DeinitIntermissions() delete pair->Value; pair->Value = NULL; } + IntermissionDescriptors.Clear(); } //========================================================================== @@ -833,7 +834,15 @@ void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int textscreen->mText << '$' << text; } textscreen->mTextDelay = 10; - textscreen->mBackground = flat; + if (flat != NULL && *flat != 0) + { + textscreen->mBackground = flat; + } + else + { + // force a black screen if no texture is set. + textscreen->mBackground = "-"; + } textscreen->mFlatfill = !finalePic; if (music != NULL && *music != 0) diff --git a/src/keysections.cpp b/src/keysections.cpp index bfec4060..8d23c958 100644 --- a/src/keysections.cpp +++ b/src/keysections.cpp @@ -44,6 +44,7 @@ #include "w_wad.h" TArray KeySections; +extern TArray KeyConfWeapons; static void LoadKeys (const char *modname, bool dbl) { @@ -159,6 +160,7 @@ void D_LoadWadSettings () ParsingKeyConf = true; KeySections.Clear(); + KeyConfWeapons.Clear(); while ((lump = Wads.FindLump ("KEYCONF", &lastlump)) != -1) { diff --git a/src/m_argv.cpp b/src/m_argv.cpp index e414ca36..457a1b33 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -230,6 +230,26 @@ FString DArgs::TakeValue(const char *check) return out; } +//=========================================================================== +// +// DArgs :: RemoveArg +// +//=========================================================================== + +void DArgs::RemoveArgs(const char *check) +{ + int i = CheckParm(check); + + if (i > 0 && i < (int)Argv.Size() - 1) + { + do + { + RemoveArg(i); + } + while (Argv[i][0] != '+' && Argv[i][0] != '-' && i < (int)Argv.Size() - 1); + } +} + //=========================================================================== // // DArgs :: GetArg diff --git a/src/m_argv.h b/src/m_argv.h index 8b4fbf2d..0fc107a0 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -54,6 +54,7 @@ public: void AppendArg(FString arg); void AppendArgs(int argc, const FString *argv); void RemoveArg(int argindex); + void RemoveArgs(const char *check); void SetArgs(int argc, char **argv); void CollectFiles(const char *param, const char *extension); DArgs *GatherFiles(const char *param) const; diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 97bda849..bdc5c3c3 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -53,9 +53,10 @@ class DLoadSaveMenu : public DListMenu { DECLARE_CLASS(DLoadSaveMenu, DListMenu) + friend void ClearSaveGames(); protected: - static TDeletingArray SaveGames; + static TArray SaveGames; static int LastSaved; static int LastAccessed; @@ -114,7 +115,7 @@ public: IMPLEMENT_CLASS(DLoadSaveMenu) -TDeletingArray DLoadSaveMenu::SaveGames; +TArray DLoadSaveMenu::SaveGames; int DLoadSaveMenu::LastSaved = -1; int DLoadSaveMenu::LastAccessed = -1; @@ -126,6 +127,21 @@ FSaveGameNode *quickSaveSlot; // //============================================================================= +void ClearSaveGames() +{ + for(unsigned i=0;iValue = NULL; } } + MenuDescriptors.Clear(); + OptionValues.Clear(); DMenu::CurrentMenu = NULL; + DefaultListMenuSettings.mItems.Clear(); + ClearSaveGames(); } //============================================================================= @@ -825,8 +831,11 @@ void M_ParseMenuDefs() OptionSettings.mFontColorHeader = V_FindFontColor(gameinfo.mFontColorHeader); OptionSettings.mFontColorHighlight = V_FindFontColor(gameinfo.mFontColorHighlight); OptionSettings.mFontColorSelection = V_FindFontColor(gameinfo.mFontColorSelection); + DefaultListMenuSettings.Reset(); + DefaultOptionMenuSettings.Reset(); atterm( DeinitMenus); + DeinitMenus(); while ((lump = Wads.FindLump ("MENUDEF", &lastlump)) != -1) { FScanner sc(lump); @@ -841,6 +850,10 @@ void M_ParseMenuDefs() else if (sc.Compare("DEFAULTLISTMENU")) { ParseListMenuBody(sc, &DefaultListMenuSettings); + if (DefaultListMenuSettings.mItems.Size() > 0) + { + I_FatalError("You cannot add menu items to the menu default settings."); + } } else if (sc.Compare("OPTIONVALUE")) { @@ -861,6 +874,10 @@ void M_ParseMenuDefs() else if (sc.Compare("DEFAULTOPTIONMENU")) { ParseOptionMenuBody(sc, &DefaultOptionMenuSettings); + if (DefaultOptionMenuSettings.mItems.Size() > 0) + { + I_FatalError("You cannot add menu items to the menu default settings."); + } } else { @@ -1221,10 +1238,11 @@ void M_CreateMenus() // THe skill menu must be refeshed each time it starts up // //============================================================================= +extern int restart; void M_StartupSkillMenu(FGameStartup *gs) { - static bool done = false; + static int done = -1; bool success = false; FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu); if (desc != NULL) @@ -1250,9 +1268,9 @@ void M_StartupSkillMenu(FGameStartup *gs) } } - if (!done) + if (done != restart) { - done = true; + done = restart; int defskill = DefaultSkill; if ((unsigned int)defskill >= AllSkills.Size()) { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 15a39987..c02c4159 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1822,6 +1822,7 @@ void P_SetLineID (line_t *ld) { ld->id = ld->args[0]; } + ld->special = 0; break; case TranslucentLine: @@ -4144,11 +4145,7 @@ static void P_Shutdown () P_DeinitKeyMessages (); P_FreeLevelData (); P_FreeExtraLevelData (); - if (StatusBar != NULL) - { - StatusBar->Destroy(); - StatusBar = NULL; - } + ST_Clear(); } #if 0 diff --git a/src/p_user.cpp b/src/p_user.cpp index a9c04ad4..831d65dd 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -133,6 +133,7 @@ void SetupPlayerClasses () { FPlayerClass newclass; + PlayerClasses.Clear(); for (unsigned i=0; iNext; if (!probe->Builtin) { + if (pNext != NULL) *pNext = probe->Next; delete[] const_cast(probe->Name); delete probe; } + else + { + pNext = &probe->Next; + } probe = next; } Environments = &Off; diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 19076055..da02bcab 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -502,6 +502,24 @@ static void AssignHexenTranslations (void) } } +//========================================================================== +// +// S_ClearSndSeq +// +//========================================================================== + +void S_ClearSndSeq() +{ + for (unsigned int i = 0; i < Sequences.Size(); i++) + { + if (Sequences[i]) + { + M_Free(Sequences[i]); + } + } + Sequences.Clear(); +} + //========================================================================== // // S_ParseSndSeq @@ -523,14 +541,7 @@ void S_ParseSndSeq (int levellump) // First free the old SNDSEQ data. This allows us to reload this for each level // and specify a level specific SNDSEQ lump! - for (unsigned int i = 0; i < Sequences.Size(); i++) - { - if (Sequences[i]) - { - M_Free(Sequences[i]); - } - } - Sequences.Clear(); + S_ClearSndSeq(); // be gone, compiler warnings stopsound = 0; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index c09e913b..4c405389 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -292,6 +292,7 @@ void S_Init () if (S_SoundCurve != NULL) { delete[] S_SoundCurve; + S_SoundCurve = NULL; } // Heretic and Hexen have sound curve lookup tables. Doom does not. diff --git a/src/st_start.h b/src/st_start.h index 3b90aa06..4ba475e7 100644 --- a/src/st_start.h +++ b/src/st_start.h @@ -42,15 +42,15 @@ public: FStartupScreen(int max_progress); virtual ~FStartupScreen(); - virtual void Progress() = 0; + virtual void Progress(); virtual void LoadingStatus(const char *message, int colors); // Used by Heretic only virtual void AppendStatusLine(const char *status); // Used by Heretic only - virtual void NetInit(const char *message, int num_players) = 0; - virtual void NetProgress(int count) = 0; - virtual void NetMessage(const char *format, ...) = 0; // cover for printf - virtual void NetDone() = 0; - virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata) = 0; + virtual void NetInit(const char *message, int num_players); + virtual void NetProgress(int count); + virtual void NetMessage(const char *format, ...); // cover for printf + virtual void NetDone(); + virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata); protected: int MaxPos, CurPos, NotchPos; }; diff --git a/src/statistics.cpp b/src/statistics.cpp index 9c07ac6d..fe72f766 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -130,11 +130,11 @@ extern TArray wadlevelinfos; static void ParseStatistics(const char *fn, TArray &statlist) { + statlist.Clear(); try { FScanner sc; sc.OpenFile(fn); - statlist.Clear(); while (sc.GetString()) { diff --git a/src/svnrevision.h b/src/svnrevision.h index 9ef7adf0..a072fb8f 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3038" -#define ZD_SVN_REVISION_NUMBER 3038 +#define ZD_SVN_REVISION_STRING "3042" +#define ZD_SVN_REVISION_NUMBER 3042 diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index 1b2f844b..0d9dfad3 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -337,6 +337,8 @@ void LoadActors () { int lastlump, lump; + StateParams.Clear(); + GlobalSymbols.ReleaseSymbols(); DropItemList.Clear(); FScriptPosition::ResetErrorCounter(); InitThingdef(); diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index 6b212414..41925b71 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -123,7 +123,8 @@ class FStateExpressions TArray expressions; public: - ~FStateExpressions(); + ~FStateExpressions() { Clear(); } + void Clear(); int Add(FxExpression *x, const PClass *o, bool c); int Reserve(int num, const PClass *cls); void Set(int num, FxExpression *x, bool cloned = false); diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 1315d70e..5f7238e2 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -2765,7 +2765,7 @@ FStateExpressions StateParams; // //========================================================================== -FStateExpressions::~FStateExpressions() +void FStateExpressions::Clear() { for(unsigned i=0; i= 0 && Wads.LumpLength (lump) >= 768) { @@ -780,6 +781,7 @@ static void FreeSpecialLights() delete[] colormap->Maps; delete colormap; } + NormalLight.Next = NULL; } // Builds NUMCOLORMAPS colormaps lit with the specified color diff --git a/src/v_video.cpp b/src/v_video.cpp index 6beb8929..26632fb6 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1605,7 +1605,7 @@ CCMD (vid_setmode) // V_Init // -void V_Init (void) +void V_Init (bool restart) { const char *i; int width, height, bits; @@ -1615,40 +1615,43 @@ void V_Init (void) // [RH] Initialize palette management InitPalette (); - width = height = bits = 0; - - if ( (i = Args->CheckValue ("-width")) ) - width = atoi (i); - - if ( (i = Args->CheckValue ("-height")) ) - height = atoi (i); - - if ( (i = Args->CheckValue ("-bits")) ) - bits = atoi (i); - - if (width == 0) + if (!restart) { - if (height == 0) + width = height = bits = 0; + + if ( (i = Args->CheckValue ("-width")) ) + width = atoi (i); + + if ( (i = Args->CheckValue ("-height")) ) + height = atoi (i); + + if ( (i = Args->CheckValue ("-bits")) ) + bits = atoi (i); + + if (width == 0) { - width = vid_defwidth; - height = vid_defheight; + if (height == 0) + { + width = vid_defwidth; + height = vid_defheight; + } + else + { + width = (height * 8) / 6; + } } - else + else if (height == 0) { - width = (height * 8) / 6; + height = (width * 6) / 8; } - } - else if (height == 0) - { - height = (width * 6) / 8; + + if (bits == 0) + { + bits = vid_defbits; + } + screen = new DDummyFrameBuffer (width, height); } - if (bits == 0) - { - bits = vid_defbits; - } - - screen = new DDummyFrameBuffer (width, height); BuildTransTable (GPalette.BaseColors); } @@ -1692,10 +1695,7 @@ void V_Shutdown() s->ObjectFlags |= OF_YesReallyDelete; delete s; } - while (FFont::FirstFont != NULL) - { - delete FFont::FirstFont; - } + V_ClearFonts(); } EXTERN_CVAR (Bool, vid_tft) diff --git a/src/v_video.h b/src/v_video.h index f4fb6f5b..ac7f6dea 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -473,7 +473,7 @@ extern "C" DWORD Col2RGB8_Inverse[65][256]; // --111111111111111111111111111111 = 0x3FFFFFFF // Allocates buffer screens, call before R_Init. -void V_Init (); +void V_Init (bool restart); // Initializes graphics mode for the first time. void V_Init2 (); diff --git a/src/xlat/parse_xlat.cpp b/src/xlat/parse_xlat.cpp index 6221c549..5edcde58 100644 --- a/src/xlat/parse_xlat.cpp +++ b/src/xlat/parse_xlat.cpp @@ -156,16 +156,23 @@ struct XlatParseContext : public FParseContext // //========================================================================== +void P_ClearTranslator() +{ + SimpleLineTranslations.Clear(); + NumBoomish = 0; + SectorTranslations.Clear(); + SectorMasks.Clear(); + memset(LineFlagTranslations, 0, sizeof(LineFlagTranslations)); + LastTranslator = ""; +} + void P_LoadTranslator(const char *lumpname) { // Only read the lump if it differs from the previous one. if (LastTranslator.CompareNoCase(lumpname)) { // Clear the old data before parsing the lump. - SimpleLineTranslations.Clear(); - NumBoomish = 0; - SectorTranslations.Clear(); - SectorMasks.Clear(); + P_ClearTranslator(); void *pParser = XlatParseAlloc(malloc); @@ -179,3 +186,5 @@ void P_LoadTranslator(const char *lumpname) LastTranslator = lumpname; } } + + diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index a833fb8b..243029f1 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -870,6 +870,7 @@ OptionMenu AutomapOptions Option "Show map label", "am_showmaplabel", "MaplabelTypes" Option "Draw map background", "am_drawmapback", "OnOff" Option "Show keys (cheat)", "am_showkeys", "OnOff" + Option "Show trigger lines", "am_showtriggerlines", "OnOff" } //------------------------------------------------------------------------------------------- @@ -922,6 +923,7 @@ OptionMenu MapColorMenu ColorPicker "Teleporter to the same map", "am_intralevelcolor" ColorPicker "Teleporter to a different map", "am_interlevelcolor" ColorPicker "Secret sector", "am_secretsectorcolor" + ColorPicker "Special trigger lines", "am_specialwallcolor" StaticText " " StaticText "Cheat Mode", 1 ColorPicker "Invisible 2-sided walls", "am_tswallcolor" @@ -939,6 +941,7 @@ OptionMenu MapColorMenu ColorPicker "Not-yet-seen walls", "am_ovunseencolor" ColorPicker "Teleporter", "am_ovtelecolor" ColorPicker "Secret sector", "am_ovsecretsectorcolor" + ColorPicker "Special trigger lines", "am_ovspecialwallcolor" StaticText " " StaticText "Overlay Cheat Mode", 1 ColorPicker "Actors", "am_ovthingcolor" From 7e4872793f4bb7c3a5f6dfa1e176836c1edf1917 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Dec 2010 21:38:10 +0000 Subject: [PATCH 64/82] - added a virtual method to DFrameBuffer that's called upon a game restart. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1130 b0f79afe-0144-0410-b225-9a4edf0717df --- src/d_main.cpp | 3 ++- src/v_video.cpp | 10 ++++++++++ src/v_video.h | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 64cfd94a..81bca294 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2328,9 +2328,10 @@ void D_DoomMain (void) { D_DoomLoop (); // never returns } - catch (CRestartException &ex) + catch (CRestartException &) { // Music and sound should be stopped first + screen->GameRestart(); S_StopMusic(true); S_StopAllChannels (); diff --git a/src/v_video.cpp b/src/v_video.cpp index 26632fb6..450650f5 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1384,6 +1384,16 @@ int DFrameBuffer::GetMaxViewPitch(bool down) return down? MAX_DN_ANGLE*ANGLE_1 : -MAX_UP_ANGLE*ANGLE_1; } +//========================================================================== +// +// DFrameBuffer :: GameRestart +// +//========================================================================== + +void DFrameBuffer::GameRestart() +{ +} + //=========================================================================== // // diff --git a/src/v_video.h b/src/v_video.h index ac7f6dea..0fb9eaf8 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -407,6 +407,9 @@ public: virtual void GetHitlist(BYTE *hitlist); virtual void PrecacheTexture(FTexture *tex, int cache); + // Report a game restart + virtual void GameRestart(); + // Screen wiping virtual bool WipeStartScreen(int type); virtual void WipeEndScreen(); From 8414b8102d636026056fac5758f4f09448879589 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Dec 2010 23:16:24 +0000 Subject: [PATCH 65/82] - GL changes for engine restart. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1131 b0f79afe-0144-0410-b225-9a4edf0717df --- src/d_main.cpp | 3 ++- src/gl/data/gl_setup.cpp | 7 ++++--- src/gl/dynlights/gl_dynlight.cpp | 3 +++ src/gl/models/gl_models.cpp | 8 ++++++++ src/gl/shaders/gl_shader.cpp | 11 +++++++++++ src/gl/shaders/gl_shader.h | 2 +- src/gl/system/gl_framebuffer.cpp | 9 +++++++++ src/gl/system/gl_framebuffer.h | 1 + src/gl/textures/gl_texture.cpp | 1 + src/p_setup.cpp | 8 +++++++- 10 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 81bca294..aaeea7e3 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2317,6 +2317,8 @@ void D_DoomMain (void) } else { + // let the renderer reinitialize some stuff if needed + screen->GameRestart(); // These calls from inside V_Init2 are still necessary C_NewModeAdjust(); M_InitVideoModesMenu(); @@ -2331,7 +2333,6 @@ void D_DoomMain (void) catch (CRestartException &) { // Music and sound should be stopped first - screen->GameRestart(); S_StopMusic(true); S_StopAllChannels (); diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index 8b6b58b2..8d7812c2 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -545,17 +545,18 @@ static void PrepareSegs() // Initialize the level data for the GL renderer // //========================================================================== +extern int restart; void gl_PreprocessLevel() { int i; - static bool datadone=false; + static int datadone=-1; - if (!datadone) + if (datadone != restart) { - datadone=true; + datadone = restart; gl_InitData(); } diff --git a/src/gl/dynlights/gl_dynlight.cpp b/src/gl/dynlights/gl_dynlight.cpp index 00b5dad3..9309f9b0 100644 --- a/src/gl/dynlights/gl_dynlight.cpp +++ b/src/gl/dynlights/gl_dynlight.cpp @@ -66,6 +66,7 @@ EXTERN_CVAR (Float, gl_lights_size); int ScriptDepth; void gl_InitGlow(FScanner &sc); void gl_ParseBrightmap(FScanner &sc, int); +void gl_DestroyUserShaders(); void gl_ParseHardwareShader(FScanner &sc, int deflump); void gl_ParseSkybox(FScanner &sc); void gl_ParseDetailTexture(FScanner &sc); @@ -1315,6 +1316,8 @@ void gl_ParseDefs() const char *defsLump = NULL; atterm( gl_ReleaseLights ); + gl_ReleaseLights(); + gl_DestroyUserShaders(); switch (gameinfo.gametype) { case GAME_Heretic: diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index cfc801b3..93cec838 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -244,6 +244,14 @@ void gl_InitModels() lastLump = 0; + for(unsigned i=0;i Date: Thu, 16 Dec 2010 00:31:18 +0000 Subject: [PATCH 66/82] - fixed: the previous bug was also present in FGLRenderer::Clear. - Fixed: D3DFB::Clear used the palette index even when a valid color was passed to it. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1132 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/renderer/gl_renderer.cpp | 2 +- src/win32/fb_d3d9.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 42d710bc..4252b940 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -538,7 +538,7 @@ void FGLRenderer::Clear(int left, int top, int right, int bottom, int palcolor, { int rt; int offY = 0; - PalEntry p = palcolor==-1? (PalEntry)color : GPalette.BaseColors[palcolor]; + PalEntry p = palcolor==-1 || color != 0? (PalEntry)color : GPalette.BaseColors[palcolor]; int width = right-left; int height= bottom-top; diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 7453571e..cc036d54 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -2763,7 +2763,7 @@ void D3DFB::Clear (int left, int top, int right, int bottom, int palcolor, uint3 { return; } - if (palcolor >= 0) + if (palcolor >= 0 && color == 0) { color = GPalette.BaseColors[palcolor]; } From 8c040e2c59750e23670b5d20f867ee1142c8ab7d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 16 Dec 2010 10:58:36 +0000 Subject: [PATCH 67/82] - Update to ZDoom e3050: * Added a 'noautosavehint' MAPINFO option. This does not actually block the autosave from happening. It just does not increase the autosave counter so any subsequent autosave in the same session will overwrite the last one which was saved with this hint on. * Added new IF_UNTOSSABLE flag for items that should be removable by any inventory function but not be droppable by the 'drop' CCMD. * Added APROP_Dormant actor property for ACS (read only!) * Fixed_ When performing a restart menus and intermissions need to be closed first. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1133 b0f79afe-0144-0410-b225-9a4edf0717df --- src/d_main.cpp | 3 +++ src/g_game.cpp | 20 ++++++++++++++++++-- src/g_level.h | 1 + src/g_mapinfo.cpp | 1 + src/g_shared/a_pickups.cpp | 2 +- src/g_shared/a_pickups.h | 4 ++-- src/p_acs.cpp | 3 +++ src/p_lnspec.cpp | 1 + src/svnrevision.h | 4 ++-- src/thingdef/thingdef_data.cpp | 3 ++- 10 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index aaeea7e3..f0a8a0c4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2336,6 +2336,9 @@ void D_DoomMain (void) S_StopMusic(true); S_StopAllChannels (); + M_ClearMenus(); // close menu if open + F_EndFinale(); // If an intermission is active, end it now + // clean up game state ST_Clear(); D_ErrorCleanup (); diff --git a/src/g_game.cpp b/src/g_game.cpp index 85bc45fc..1d735ee0 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1904,6 +1904,7 @@ FString G_BuildSaveName (const char *prefix, int slot) } CVAR (Int, autosavenum, 0, CVAR_NOSET|CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +static int nextautosave = -1; CVAR (Int, disableautosave, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, autosavecount, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { @@ -1924,10 +1925,25 @@ void G_DoAutoSave () const char *readableTime; int count = autosavecount != 0 ? autosavecount : 1; - num.Int = (autosavenum + 1) % count; + if (nextautosave == -1) + { + nextautosave = (autosavenum + 1) % count; + } + + num.Int = nextautosave; autosavenum.ForceSet (num, CVAR_Int); - file = G_BuildSaveName ("auto", num.Int); + file = G_BuildSaveName ("auto", nextautosave); + + if (!(level.flags2 & LEVEL2_NOAUTOSAVEHINT)) + { + nextautosave = (nextautosave + 1) % count; + } + else + { + // This flag can only be used once per level + level.flags2 &= ~LEVEL2_NOAUTOSAVEHINT; + } readableTime = myasctime (); strcpy (description, "Autosave "); diff --git a/src/g_level.h b/src/g_level.h index 6cb9d844..34c2bf5f 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -212,6 +212,7 @@ enum ELevelFlags LEVEL2_NOSTATISTICS = 0x10000000, // This level should not have statistics collected LEVEL2_ENDGAME = 0x20000000, // This is an epilogue level that cannot be quit. + LEVEL2_NOAUTOSAVEHINT = 0x40000000, // tell the game that an autosave for this level does not need to be kept }; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 4199305d..b4183ef2 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1238,6 +1238,7 @@ MapFlagHandlers[] = { "resethealth", MITYPE_SETFLAG2, LEVEL2_RESETHEALTH, 0 }, { "endofgame", MITYPE_SETFLAG2, LEVEL2_ENDGAME, 0 }, { "nostatistics", MITYPE_SETFLAG2, LEVEL2_NOSTATISTICS, 0 }, + { "noautosavehint", MITYPE_SETFLAG2, LEVEL2_NOAUTOSAVEHINT, 0 }, { "unfreezesingleplayerconversations",MITYPE_SETFLAG2, LEVEL2_CONV_SINGLE_UNFREEZE, 0 }, { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes { "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX}, diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index f059d8d3..baa37d56 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -628,7 +628,7 @@ AInventory *AInventory::CreateTossable () { return NULL; } - if ((ItemFlags & IF_UNDROPPABLE) || Owner == NULL || Amount <= 0) + if ((ItemFlags & (IF_UNDROPPABLE|IF_UNTOSSABLE)) || Owner == NULL || Amount <= 0) { return NULL; } diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 3afcbf5b..23cac960 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -116,10 +116,10 @@ enum IF_PICKUPGOOD = 1<<2, // HandlePickup wants normal pickup FX to happen IF_QUIET = 1<<3, // Don't give feedback when picking up IF_AUTOACTIVATE = 1<<4, // Automatically activate item on pickup - IF_UNDROPPABLE = 1<<5, // The player cannot manually drop the item + IF_UNDROPPABLE = 1<<5, // Item cannot be removed unless done explicitly with RemoveInventory IF_INVBAR = 1<<6, // Item appears in the inventory bar IF_HUBPOWER = 1<<7, // Powerup is kept when moving in a hub -// IF_INTERHUBSTRIP = 1<<8, // Item is removed when travelling between hubs + IF_UNTOSSABLE = 1<<8, // The player cannot manually drop the item IF_ADDITIVETIME = 1<<9, // when picked up while another item is active, time is added instead of replaced. IF_ALWAYSPICKUP = 1<<10, // For IF_AUTOACTIVATE, MaxAmount=0 items: Always "pick up", even if it doesn't do anything IF_FANCYPICKUPSOUND = 1<<11, // Play pickup sound in "surround" mode diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 7a477acc..63c3f0a6 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2541,6 +2541,7 @@ enum APROP_WaterLevel = 28, APROP_ScaleX = 29, APROP_ScaleY = 30, + APROP_Dormant = 31, }; // These are needed for ACS's APROP_RenderStyle @@ -2769,6 +2770,7 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_Friendly: return !!(actor->flags & MF_FRIENDLY); case APROP_Notarget: return !!(actor->flags3 & MF3_NOTARGET); case APROP_Notrigger: return !!(actor->flags6 & MF6_NOTRIGGER); + case APROP_Dormant: return !!(actor->flags2 & MF2_DORMANT); case APROP_SpawnHealth: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) { return static_cast(actor)->MaxHealth; @@ -2841,6 +2843,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_Friendly: case APROP_Notarget: case APROP_Notrigger: + case APROP_Dormant: return (GetActorProperty(tid, property) == (!!value)); // Strings are not covered by GetActorProperty, so make the check here diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index ac752017..1b3f627a 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2798,6 +2798,7 @@ FUNC(LS_Autosave) { if (gameaction != ga_savegame) { + level.flags2 &= ~LEVEL2_NOAUTOSAVEHINT; Net_WriteByte (DEM_CHECKAUTOSAVE); } return true; diff --git a/src/svnrevision.h b/src/svnrevision.h index a072fb8f..7124168f 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3042" -#define ZD_SVN_REVISION_NUMBER 3042 +#define ZD_SVN_REVISION_STRING "3050" +#define ZD_SVN_REVISION_NUMBER 3050 diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 30c35a0a..f85d5cd6 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -279,12 +279,13 @@ static FFlagDef InventoryFlags[] = DEFINE_FLAG(IF, UNDROPPABLE, AInventory, ItemFlags), DEFINE_FLAG(IF, INVBAR, AInventory, ItemFlags), DEFINE_FLAG(IF, HUBPOWER, AInventory, ItemFlags), + DEFINE_FLAG(IF, UNTOSSABLE, AInventory, ItemFlags), + DEFINE_FLAG(IF, ADDITIVETIME, AInventory, ItemFlags), DEFINE_FLAG(IF, ALWAYSPICKUP, AInventory, ItemFlags), DEFINE_FLAG(IF, FANCYPICKUPSOUND, AInventory, ItemFlags), DEFINE_FLAG(IF, BIGPOWERUP, AInventory, ItemFlags), DEFINE_FLAG(IF, KEEPDEPLETED, AInventory, ItemFlags), DEFINE_FLAG(IF, IGNORESKILL, AInventory, ItemFlags), - DEFINE_FLAG(IF, ADDITIVETIME, AInventory, ItemFlags), DEFINE_FLAG(IF, NOATTENPICKUPSOUND, AInventory, ItemFlags), DEFINE_FLAG(IF, PERSISTENTPOWER, AInventory, ItemFlags), From f9fbe218baba5b53a45c0bfd6f18254a317ea7f1 Mon Sep 17 00:00:00 2001 From: gez Date: Mon, 20 Dec 2010 11:22:17 +0000 Subject: [PATCH 68/82] * Updated to ZDoom r3061: - Added HexenArmor to AltHud. - Clamp parameter to P_GiveBody to prevent overflows. - Fixed: The Floor_RaiseAndCrush types in Doom wait if blocked, therefore need Hexen crush mode. - Fixed: Angle conversion in P_SpawnMapThing did not work for negative values due to use of an unsigned multiplication. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1135 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_shared/a_pickups.cpp | 1 + src/g_shared/shared_hud.cpp | 59 ++++++++++++++++++++++++++++++------- src/p_mobj.cpp | 2 +- src/svnrevision.h | 4 +-- wadsrc/static/xlat/base.txt | 8 ++--- 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index baa37d56..f15da2f3 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -184,6 +184,7 @@ bool P_GiveBody (AActor *actor, int num) int max; player_t *player = actor->player; + num = clamp(num, -65536, 65536); // prevent overflows for bad values if (player != NULL) { max = static_cast(actor)->GetMaxHealth() + player->stamina; diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 9901c794..72e780f5 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -283,16 +283,42 @@ static void DrawHealth(int health, int x, int y) //=========================================================================== // // Draw Armor. -// very similar to drawhealth. +// very similar to drawhealth, but adapted to handle Hexen armor too // //=========================================================================== -static void DrawArmor(AInventory * armor, int x, int y) +static void DrawArmor(ABasicArmor * barmor, AHexenArmor * harmor, int x, int y) { - if (armor) - { - int ap=armor->Amount; + int ap = 0; + int bestslot = 4; + if (harmor) + { + int ac = (harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]); + ac >>= FRACBITS; + ap += ac; + + if (ac) + { + // Find the part of armor that protects the most + bestslot = 0; + for (int i = 1; i < 4; ++i) + { + if (harmor->Slots[i] > harmor->Slots[bestslot]) + { + bestslot = i; + } + } + } + } + + if (barmor) + { + ap += barmor->Amount; + } + + if (ap) + { // decide on color int fontcolor = ap < hud_armor_red ? CR_RED : @@ -301,11 +327,23 @@ static void DrawArmor(AInventory * armor, int x, int y) CR_BLUE; - if (ap) + // Use the sprite of one of the predefined Hexen armor bonuses. + // This is not a very generic approach, but it is not possible + // to truly create new types of Hexen armor bonus items anyway. + if (harmor && bestslot < 4) { - DrawImageToBox(TexMan[armor->Icon], x, y, 31, 17); - DrawHudNumber(HudFont, fontcolor, ap, x + 33, y + 17); + char icon[] = "AR_1A0"; + switch (bestslot) + { + case 1: icon[3] = '2'; break; + case 2: icon[3] = '3'; break; + case 3: icon[3] = '4'; break; + default: break; + } + DrawImageToBox(TexMan.FindTexture(icon, FTexture::TEX_Sprite), x, y, 31, 17); } + else if (barmor) DrawImageToBox(TexMan[barmor->Icon], x, y, 31, 17); + DrawHudNumber(HudFont, fontcolor, ap, x + 33, y + 17); } } @@ -815,9 +853,8 @@ void DrawHUD() DrawFrags(CPlayer, 5, hudheight-70); } DrawHealth(CPlayer->health, 5, hudheight-45); - // Yes, that doesn't work properly for Hexen but frankly, I have no - // idea how to make a meaningful value out of Hexen's armor system! - DrawArmor(CPlayer->mo->FindInventory(RUNTIME_CLASS(ABasicArmor)), 5, hudheight-20); + DrawArmor(CPlayer->mo->FindInventory(), + CPlayer->mo->FindInventory(), 5, hudheight-20); i=DrawKeys(CPlayer, hudwidth-4, hudheight-10); i=DrawAmmo(CPlayer, hudwidth-5, i); DrawWeapons(CPlayer, hudwidth-5, i); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0b13c8c7..fbf6b28a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4336,7 +4336,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->tid = mthing->thingid; mobj->AddToHash (); - mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360); + mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * CONST64(0x100000000)) / 360); // Check if this actor's mapthing has a conversation defined if (mthing->Conversation > 0) diff --git a/src/svnrevision.h b/src/svnrevision.h index 7124168f..21e3bcf4 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3050" -#define ZD_SVN_REVISION_NUMBER 3050 +#define ZD_SVN_REVISION_STRING "3061" +#define ZD_SVN_REVISION_NUMBER 3061 diff --git a/wadsrc/static/xlat/base.txt b/wadsrc/static/xlat/base.txt index 9ffd409d..80ae814d 100644 --- a/wadsrc/static/xlat/base.txt +++ b/wadsrc/static/xlat/base.txt @@ -54,8 +54,8 @@ include "xlat/defines.i" 52 = WALK, Exit_Normal (0) 53 = WALK, Plat_PerpetualRaiseLip (tag, P_SLOW, PLATWAIT, 0) 54 = WALK, Plat_Stop (tag) - 55 = USE, Floor_RaiseAndCrush (tag, F_SLOW, 10) - 56 = WALK, Floor_RaiseAndCrush (tag, F_SLOW, 10) + 55 = USE, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) + 56 = WALK, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) 57 = WALK, Ceiling_CrushStop (tag) 58 = WALK, Floor_RaiseByValue (tag, F_SLOW, 24) 59 = WALK, Floor_RaiseByValueTxTy (tag, F_SLOW, 24) @@ -64,7 +64,7 @@ include "xlat/defines.i" 62 = USE|REP, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) 63 = USE|REP, Door_Raise (tag, D_SLOW, VDOORWAIT) 64 = USE|REP, Floor_RaiseToLowestCeiling (tag, F_SLOW) - 65 = USE|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10) + 65 = USE|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) 66 = USE|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 3) 67 = USE|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 4) 68 = USE|REP, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) @@ -93,7 +93,7 @@ include "xlat/defines.i" 91 = WALK|REP, Floor_RaiseToLowestCeiling (tag, F_SLOW) 92 = WALK|REP, Floor_RaiseByValue (tag, F_SLOW, 24) 93 = WALK|REP, Floor_RaiseByValueTxTy (tag, F_SLOW, 24) - 94 = WALK|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10) + 94 = WALK|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) 95 = WALK|REP, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) 96 = WALK|REP, Floor_RaiseByTexture (tag, F_SLOW) 97 = WALK|REP|MONST, Teleport (0, tag) From 324fe526da68606a70132f745f68274a2dae62cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Dec 2010 11:58:08 +0000 Subject: [PATCH 69/82] - removed all code related to portal shape maintenance because it's not needed anymore. The recently implemented map sections and portal coverage cover the same task more efficiently. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1136 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.h | 6 -- src/gl/data/gl_portaldata.cpp | 157 +--------------------------------- src/gl/data/gl_setup.cpp | 2 + src/gl/scene/gl_portal.cpp | 134 ----------------------------- src/gl/scene/gl_portal.h | 2 - src/gl/scene/gl_sprite.cpp | 3 + 6 files changed, 6 insertions(+), 298 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index 42e12878..ba4a78b7 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -33,18 +33,12 @@ struct GLSectorStackPortal; struct FPortal { - TArray Shape; // forms the smallest convex outline around the portal area - TArray ClipAngles; fixed_t xDisplacement; fixed_t yDisplacement; int plane; AStackPoint *origin; GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! - int PointOnShapeLineSide(fixed_t x, fixed_t y, int shapeindex); - void AddVertexToShape(vertex_t *vertex); - void AddSectorToPortal(sector_t *sector); - void UpdateClipAngles(); GLSectorStackPortal *GetGLPortal(); }; diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index b72e42bb..a8031f84 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -71,145 +71,6 @@ TArray portals; // //========================================================================== -int FPortal::PointOnShapeLineSide(fixed_t x, fixed_t y, int shapeindex) -{ - int shapeindex2 = (shapeindex+1)%Shape.Size(); - - return DMulScale32(y - Shape[shapeindex]->y, Shape[shapeindex2]->x - Shape[shapeindex]->x, - Shape[shapeindex]->x - x, Shape[shapeindex2]->y - Shape[shapeindex]->y); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FPortal::AddVertexToShape(vertex_t *vertex) -{ - for(unsigned i=0;ix == Shape[i]->x && vertex->y == Shape[i]->y) return; - } - - if (Shape.Size() < 2) - { - Shape.Push(vertex); - } - else if (Shape.Size() == 2) - { - // Special case: We need to check if the vertex is on an extension of the line between the first two vertices. - int pos = PointOnShapeLineSide(vertex->x, vertex->y, 0); - - if (pos == 0) - { - fixed_t distv1 = P_AproxDistance(vertex->x - Shape[0]->x, vertex->y - Shape[0]->y); - fixed_t distv2 = P_AproxDistance(vertex->x - Shape[1]->x, vertex->y - Shape[1]->y); - fixed_t distvv = P_AproxDistance(Shape[0]->x - Shape[1]->x, Shape[0]->y - Shape[1]->y); - - if (distv1 > distvv) - { - Shape[1] = vertex; - } - else if (distv2 > distvv) - { - Shape[0] = vertex; - } - return; - } - else if (pos > 0) - { - Shape.Insert(1, vertex); - } - else - { - Shape.Push(vertex); - } - } - else - { - for(unsigned i=0; ix, vertex->y, i); - if (startlinepos >= 0) - { - int previouslinepos = PointOnShapeLineSide(vertex->x, vertex->y, (i+Shape.Size()-1)%Shape.Size()); - - if (previouslinepos < 0) // we found the first line for which the vertex lies in front - { - unsigned int nextpoint = i; - - do - { - nextpoint = (nextpoint+1) % Shape.Size(); - } - while (PointOnShapeLineSide(vertex->x, vertex->y, nextpoint) >= 0); - - int removecount = (nextpoint - i + Shape.Size()) % Shape.Size() - 1; - - if (removecount == 0) - { - if (startlinepos > 0) - { - Shape.Insert(i+1, vertex); - } - } - else if (nextpoint > i || nextpoint == 0) - { - // The easy case: It doesn't wrap around - Shape.Delete(i+1, removecount-1); - Shape[i+1] = vertex; - } - else - { - // It does wrap around. - Shape.Delete(i+1, removecount); - Shape.Delete(1, nextpoint-1); - Shape[0] = vertex; - } - return; - } - } - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FPortal::AddSectorToPortal(sector_t *sector) -{ - for(int i=0; ilinecount; i++) - { - AddVertexToShape(sector->lines[i]->v1); - // This is necessary to handle unclosed sectors - AddVertexToShape(sector->lines[i]->v2); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FPortal::UpdateClipAngles() -{ - for(unsigned int i=0; ix, Shape[i]->y); - } -} - -//========================================================================== -// -// -// -//========================================================================== - GLSectorStackPortal *FPortal::GetGLPortal() { if (glportal == NULL) glportal = new GLSectorStackPortal(this); @@ -506,7 +367,6 @@ void gl_InitPortals() portalp[plane]->yDisplacement = pt->y - pt->Mate->y; portals.Push(portalp[plane]); } - portalp[plane]->AddSectorToPortal(§ors[i]); sectors[i].portals[plane] = portalp[plane]; for (int j=0;j < sectors[i].subsectorcount; j++) @@ -517,17 +377,6 @@ void gl_InitPortals() } } } - - for(unsigned i=0;iShape.Reserve(1); - portals[i]->Shape.Last() = portals[i]->Shape[0]; - portals[i]->Shape.ShrinkToFit(); - portals[i]->ClipAngles.Resize(portals[i]->Shape.Size()); - } } @@ -537,12 +386,8 @@ CCMD(dumpportals) { double xdisp = portals[i]->xDisplacement/65536.; double ydisp = portals[i]->yDisplacement/65536.; - Printf(PRINT_LOG, "Portal #%d, %s, stackpoint at (%f,%f), displacement = (%f,%f)\nShape:\n", i, portals[i]->plane==0? "floor":"ceiling", portals[i]->origin->x/65536., portals[i]->origin->y/65536., + Printf(PRINT_LOG, "Portal #%d, %s, stackpoint at (%f,%f), displacement = (%f,%f)\n", i, portals[i]->plane==0? "floor":"ceiling", portals[i]->origin->x/65536., portals[i]->origin->y/65536., xdisp, ydisp); - for (unsigned j=0;jShape.Size(); j++) - { - Printf(PRINT_LOG, "\t(%f,%f)\n", portals[i]->Shape[j]->x/65536. + xdisp, portals[i]->Shape[j]->y/65536. + ydisp); - } Printf(PRINT_LOG, "Coverage:\n"); for(int j=0;jUpdateClipAngles(); viewx += origin->origin->x - origin->origin->Mate->x; viewy += origin->origin->y - origin->origin->Mate->y; @@ -744,139 +743,6 @@ void GLSectorStackPortal::DrawContents() if (origin->plane != -1) instack[origin->plane]--; } -//----------------------------------------------------------------------------- -// -// GLSectorStackPortal::ClipSeg -// -//----------------------------------------------------------------------------- -int GLSectorStackPortal::ClipSeg(seg_t *seg) -{ - FPortal *portal = origin; - angle_t *angles = &portal->ClipAngles[0]; - unsigned numpoints = portal->ClipAngles.Size()-1; - angle_t clipangle = seg->v1->GetClipAngle(); - unsigned i, j; - int relation; - - // Check the front side of the portal. Anything in front of the shape must be discarded by the clipper. - for(i=0;i ANGLE_180 && angles[i+1] - angles[i] < ANGLE_180) - { - relation = DMulScale32(seg->v1->y - portal->Shape[i]->y - portal->yDisplacement, portal->Shape[i+1]->x - portal->Shape[i]->x, - portal->Shape[i]->x - seg->v1->x + portal->xDisplacement, portal->Shape[i+1]->y - portal->Shape[i]->y); - if (relation > 0) - { - return PClip_InFront; - } - else if (relation == 0) - { - // If this vertex is on the boundary we need to check the second one, too. The line may be partially inside the shape - // but outside the portal. We can use the same boundary line for this - relation = DMulScale32(seg->v2->y - portal->Shape[i]->y - portal->yDisplacement, portal->Shape[i+1]->x - portal->Shape[i]->x, - portal->Shape[i]->x - seg->v2->x + portal->xDisplacement, portal->Shape[i+1]->y - portal->Shape[i]->y); - if (relation >= 0) return PClip_InFront; - } - return PClip_Inside; - } - } - - // The first vertex did not yield any useful result. Check the second one. - clipangle = seg->v2->GetClipAngle(); - for(j=0;j ANGLE_180 && angles[j+1] - angles[j] < ANGLE_180) - { - relation = DMulScale32(seg->v2->y - portal->Shape[j]->y - portal->yDisplacement, portal->Shape[j+1]->x - portal->Shape[j]->x, - portal->Shape[j]->x - seg->v2->x + portal->xDisplacement, portal->Shape[j+1]->y - portal->Shape[j]->y); - if (relation > 0) - { - return PClip_InFront; - } - else if (relation == 0) - { - // If this vertex is on the boundary we need to check the other one, too. The line may be partially inside the shape - // but outside the portal. We can use the same boundary line for this - relation = DMulScale32(seg->v1->y - portal->Shape[j]->y - portal->yDisplacement, portal->Shape[j+1]->x - portal->Shape[j]->x, - portal->Shape[j]->x - seg->v1->x + portal->xDisplacement, portal->Shape[j+1]->y - portal->Shape[j]->y); - if (relation >= 0) return PClip_InFront; - } - return PClip_Inside; - } - } - return PClip_Inside; // The viewpoint is inside the portal - -#if 0 - // Check backside of portal - for(i=0;i ANGLE_180 && angles[i] - clipangle <= ANGLE_180) - { - relation1 = DMulScale32(seg->v1->y - portal->Shape[i]->y - portal->yDisplacement, portal->Shape[i+1]->x - portal->Shape[i]->x, - portal->Shape[i]->x - seg->v1->x + portal->xDisplacement, portal->Shape[i+1]->y - portal->Shape[i]->y); - if (relation1 < 0) return PClip_Inside; - // If this vertex is inside we need to check the second one, too. The line may be partially inside the shape - // but outside the portal. - break; - } - } - - clipangle = seg->v2->GetClipAngle(); - for(j=0;j ANGLE_180 && angles[j] - clipangle <= ANGLE_180) - { - relation2 = DMulScale32(seg->v2->y - portal->Shape[j]->y - portal->yDisplacement, portal->Shape[j+1]->x - portal->Shape[j]->x, - portal->Shape[j]->x - seg->v2->x + portal->xDisplacement, portal->Shape[j+1]->y - portal->Shape[j]->y); - if (relation2 < 0) return PClip_Inside; - break; - } - } - return PClip_Behind; -#endif -} - - -//----------------------------------------------------------------------------- -// -// GLSectorStackPortal::ClipPoint -// -//----------------------------------------------------------------------------- -int GLSectorStackPortal::ClipPoint(fixed_t x, fixed_t y) -{ - FPortal *portal = origin; - angle_t *angles = &portal->ClipAngles[0]; - unsigned numpoints = portal->ClipAngles.Size()-1; - angle_t clipangle = R_PointToPseudoAngle(viewx, viewy, x, y); - unsigned i; - - for(i=0;i ANGLE_180 && angles[i+1] - angles[i] < ANGLE_180) - { - int relation = DMulScale32(y - portal->Shape[i]->y - portal->yDisplacement, portal->Shape[i+1]->x - portal->Shape[i]->x, - portal->Shape[i]->x - x + portal->xDisplacement, portal->Shape[i+1]->y - portal->Shape[i]->y); - if (relation > 0) return PClip_InFront; - return PClip_Inside; - } - } - return PClip_Inside; - - /* - for(i=0;i= angles[i] && clipangle < angles[i+1]) - { - int relation = DMulScale32(y - portal->Shape[i]->y, portal->Shape[i+1]->x - portal->Shape[i]->x, - portal->Shape[i]->x - x, portal->Shape[i+1]->y - portal->Shape[i]->y); - if (relation > 0) return PClip_InFront; - return PClip_Inside; - } - } - */ - return PClip_Inside; -} - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index da99838e..5f152135 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -250,8 +250,6 @@ public: { origin=pt; } - int ClipSeg(seg_t *seg); - int ClipPoint(fixed_t x, fixed_t y); void SetupCoverage(); void AddSubsector(subsector_t *sub) { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index ffc37d37..3506b4ec 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -446,6 +446,9 @@ void GLSprite::Process(AActor* thing,sector_t * sector) return; } + // If this thing is in a map section that's not in view it can't possible be visible + if (!(currentmapsection[thing->subsector->mapsection>>3] & (1 << (thing->subsector->mapsection & 7)))) return; + // [RH] Interpolate the sprite's position to make it look smooth fixed_t thingx = thing->PrevX + FixedMul (r_TicFrac, thing->x - thing->PrevX); fixed_t thingy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY); From ed492a6423a630e877c028eca854bdc224a95596 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Dec 2010 13:23:34 +0000 Subject: [PATCH 70/82] - why was this commented out? git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1139 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_bsp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 4bf311b8..ec1e968c 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -551,7 +551,7 @@ void gl_RenderBSPNode (void *node) // It is not necessary to use the slower precise version here if (!clipper.CheckBox(bsp->bbox[side])) { - //if (!(gl_drawinfo->no_renderflags[bsp-nodes] & SSRF_SEEN)) + if (!(gl_drawinfo->no_renderflags[bsp-nodes] & SSRF_SEEN)) return; } From 5bb69adf51300c2abb9d5bec7c98a36c74376e6f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Dec 2010 13:27:20 +0000 Subject: [PATCH 71/82] - initialize portals only from map displacement. This is fully sufficient for GL rendering and avoids creating redundant portals. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1140 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_portaldata.cpp | 121 ++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 33 deletions(-) diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index a8031f84..2d614e4e 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -63,6 +63,30 @@ #include "gl/utility/gl_clock.h" #include "gl/gl_functions.h" +struct FPortalID +{ + fixed_t mXDisplacement; + fixed_t mYDisplacement; + + // for the hash code + operator intptr_t() const { return (mXDisplacement >> 8) + (mYDisplacement << 8); } + bool operator != (const FPortalID &other) const + { + return mXDisplacement != other.mXDisplacement || + mYDisplacement != other.mYDisplacement; + } +}; + +struct FPortalSector +{ + sector_t *mSub; + int mPlane; +}; + +typedef TArray FPortalSectors; + +typedef TMap FPortalMap; + TArray portals; //========================================================================== @@ -326,10 +350,36 @@ void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, F // //========================================================================== +static void CollectPortalSectors(FPortalMap &collection) +{ + for (int i=0;iCeilingSkyBox != NULL && sec->CeilingSkyBox->bAlways && sec->CeilingSkyBox->Mate != NULL) + { + FPortalID id = { sec->CeilingSkyBox->x - sec->CeilingSkyBox->Mate->x, + sec->CeilingSkyBox->y - sec->CeilingSkyBox->Mate->y}; + + FPortalSectors &sss = collection[id]; + FPortalSector ss = { sec, sector_t::ceiling }; + sss.Push(ss); + } + + if (sec->FloorSkyBox != NULL && sec->FloorSkyBox->bAlways && sec->FloorSkyBox->Mate != NULL) + { + FPortalID id = { sec->FloorSkyBox->x - sec->FloorSkyBox->Mate->x, + sec->FloorSkyBox->y - sec->FloorSkyBox->Mate->y }; + + FPortalSectors &sss = collection[id]; + FPortalSector ss = { sec, sector_t::floor }; + sss.Push(ss); + } + } +} + void gl_InitPortals() { - TThinkerIterator it; - AStackPoint *pt; + FPortalMap collection; if (numnodes == 0) return; @@ -341,59 +391,64 @@ void gl_InitPortals() no->len = (float)sqrt(fdx * fdx + fdy * fdy); } + CollectPortalSectors(collection); portals.Clear(); - while ((pt = it.Next())) + + FPortalMap::Iterator it(collection); + FPortalMap::Pair *pair; + int c = 0; + int planeflags = 0; + while (it.NextPair(pair)) { - FPortal *portalp[2] = {NULL, NULL}; - for(int i=0;iValue.Size(); i++) { - if (sectors[i].linecount == 0) + if (pair->Value[i].mPlane == sector_t::floor) planeflags |= 1; + else if (pair->Value[i].mPlane == sector_t::ceiling) planeflags |= 2; + } + for (int i=1;i<=2;i<<=1) + { + // For now, add separate portals for floor and ceiling. They can be merged once + // proper plane clipping is in. + if (planeflags & i) { - continue; - } - for(int plane=0;plane<2;plane++) - { - TObjPtr &p = plane==1? sectors[i].CeilingSkyBox : sectors[i].FloorSkyBox; - if (p != pt) continue; - - // we only process portals that actually are in use. - if (portalp[plane] == NULL) + FPortal *portal = new FPortal; + portal->xDisplacement = pair->Key.mXDisplacement; + portal->yDisplacement = pair->Key.mYDisplacement; + portal->plane = (i==1? sector_t::floor : sector_t::ceiling); /**/ + portals.Push(portal); + for(unsigned j=0;jValue.Size(); j++) { - portalp[plane] = new FPortal; - portalp[plane]->origin = pt; - portalp[plane]->glportal = NULL; - portalp[plane]->plane = plane; - portalp[plane]->xDisplacement = pt->x - pt->Mate->x; - portalp[plane]->yDisplacement = pt->y - pt->Mate->y; - portals.Push(portalp[plane]); - } - sectors[i].portals[plane] = portalp[plane]; - - for (int j=0;j < sectors[i].subsectorcount; j++) - { - subsector_t *sub = sectors[i].subsectors[j]; - gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, portalp[plane]); + sector_t *sec = pair->Value[j].mSub; + int plane = pair->Value[j].mPlane; + if (portal->plane == plane) + { + for(int k=0;ksubsectorcount; k++) + { + subsector_t *sub = sec->subsectors[k]; + gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, portal); + } + sec->portals[plane] = portal; + } } } } } } - CCMD(dumpportals) { for(unsigned i=0;ixDisplacement/65536.; double ydisp = portals[i]->yDisplacement/65536.; - Printf(PRINT_LOG, "Portal #%d, %s, stackpoint at (%f,%f), displacement = (%f,%f)\n", i, portals[i]->plane==0? "floor":"ceiling", portals[i]->origin->x/65536., portals[i]->origin->y/65536., + Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, portals[i]->plane==0? "floor":"ceiling", xdisp, ydisp); Printf(PRINT_LOG, "Coverage:\n"); for(int j=0;jplane == 0? sub->render_sector->FloorSkyBox : sub->render_sector->CeilingSkyBox; - if (pt == portals[i]->origin) + FPortal *port = sub->render_sector->portals[portals[i]->plane]; + if (port == portals[i]) { Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", j, sub->render_sector->sectornum); for(unsigned k = 0;k< sub->numlines; k++) From c5b112cc919ee8d519b649e24d0303a74cc0ee40 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Dec 2010 16:35:07 +0000 Subject: [PATCH 72/82] - missed one spot where the obsolete 'origin' variable in FPortal was still used. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1142 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_data.h | 1 - src/gl/scene/gl_portal.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index ba4a78b7..4bf611f8 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -36,7 +36,6 @@ struct FPortal fixed_t xDisplacement; fixed_t yDisplacement; int plane; - AStackPoint *origin; GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! GLSectorStackPortal *GetGLPortal(); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index e9516480..fcba91d0 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -722,8 +722,8 @@ void GLSectorStackPortal::DrawContents() { FPortal *portal = origin; - viewx += origin->origin->x - origin->origin->Mate->x; - viewy += origin->origin->y - origin->origin->Mate->y; + viewx += origin->xDisplacement; + viewy += origin->yDisplacement; GLRenderer->mViewActor = NULL; GLRenderer->mCurrentPortal = this; From 3aa9aa1dc67d4bfd6bd2617afcdf14bdfb586810 Mon Sep 17 00:00:00 2001 From: gez Date: Fri, 24 Dec 2010 18:43:14 +0000 Subject: [PATCH 73/82] * Updated to ZDoom r3072: - Removed all portal fudging that was necessary to make thing based portals work the same as line based portals. Using an actor flag on the skybox thing the visplane code now checks what kind of portal is used and uses the proper logic accordingly. As a result the "Portals" compatibility flag no longer exists. - Added Chris's crashcatcher improvements. - Fixed: CreateCachedNodes did not free its file buffer. - Fixed: The background on some bars was cliped incorrectly. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1143 b0f79afe-0144-0410-b225-9a4edf0717df --- src/compatibility.cpp | 7 --- src/d_iwad.cpp | 1 - src/g_shared/sbarinfo.cpp | 2 +- src/gi.h | 1 - src/p_glnodes.cpp | 1 + src/p_spec.cpp | 78 -------------------------------- src/r_plane.cpp | 2 +- src/sdl/crashcatcher.c | 91 +++++++------------------------------- src/svnrevision.h | 4 +- wadsrc/static/iwadinfo.txt | 1 - 10 files changed, 22 insertions(+), 166 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index cd74f5e3..718bfece 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -90,7 +90,6 @@ static FCompatOption Options[] = { "resetplayerspeed", 0, BCOMPATF_RESETPLAYERSPEED }, { "vileghosts", 0, BCOMPATF_VILEGHOSTS }, { "ignoreteleporttags", 0, BCOMPATF_BADTELEPORTERS }, - { "oldportals", 0, BCOMPATF_BADPORTALS }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, 0 }, @@ -284,12 +283,6 @@ void CheckCompatibility(MapData *map) ib_compatflags = 0; ii_compatparams = -1; } - else if (Wads.GetLumpFile(map->lumpnum) == 1 && (gameinfo.flags & GI_COMPATPORTAL)) - { - ii_compatflags = 0; - ib_compatflags = BCOMPATF_BADPORTALS; - ii_compatparams = -1; - } else { map->GetChecksum(md5.Bytes); diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 0c7cc3bf..0999a77e 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -174,7 +174,6 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize) else if(sc.Compare("Extended")) iwad->flags |= GI_MENUHACK_EXTENDED; else if(sc.Compare("Shorttex")) iwad->flags |= GI_COMPATSHORTTEX; else if(sc.Compare("Stairs")) iwad->flags |= GI_COMPATSTAIRS; - else if(sc.Compare("Portals")) iwad->flags |= GI_COMPATPORTAL; else sc.ScriptError(NULL); } while (sc.CheckString(",")); diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index a552a3ad..c469bb73 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -1190,7 +1190,7 @@ public: } if(clearDontDraw) - screen->Clear(static_cast(MAX(dx, dcx)), static_cast(MAX(dy, dcy)), static_cast(dcr), static_cast(dcb), GPalette.BlackIndex, 0); + screen->Clear(static_cast(MAX(dx, dcx)), static_cast(MAX(dy, dcy)), static_cast(MIN(dcr,w+MAX(dx, dcx))), static_cast(MIN(dcb,MAX(dy, dcy)+h)), GPalette.BlackIndex, 0); else { if(alphaMap) diff --git a/src/gi.h b/src/gi.h index 645f5d3b..647db1a9 100644 --- a/src/gi.h +++ b/src/gi.h @@ -47,7 +47,6 @@ #define GI_COMPATPOLY1 0x00000040 // Hexen's MAP36 needs old polyobject drawing #define GI_COMPATPOLY2 0x00000080 // so does HEXDD's MAP47 #define GI_NOTEXTCOLOR 0x00000100 // Chex Quest 3 would have everything green -#define GI_COMPATPORTAL 0x00000200 // Urban Brawl relies on the old portal code #include "gametype.h" diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index c48d72e8..4d34c704 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1223,6 +1223,7 @@ static void CreateCachedNodes(MapData *map) FILE *f = fopen(path, "wb"); fwrite(compressed, 1, outlen+offset, f); fclose(f); + delete [] compressed; } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index dd3e0ca1..cf97c16f 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -921,39 +921,6 @@ static bool SpreadCeilingPortal(AStackPoint *pt, fixed_t alpha, sector_t *sector return fail; } -static bool SpreadFloorPortal(AStackPoint *pt, fixed_t alpha, sector_t *sector) -{ - bool fail = false; - sector->validcount = validcount; - for(int i=0; ilinecount; i++) - { - line_t *line = sector->lines[i]; - sector_t *backsector = sector == line->frontsector? line->backsector : line->frontsector; - if (line->backsector == line->frontsector) continue; - if (backsector == NULL) { fail = true; continue; } - if (backsector->validcount == validcount) continue; - if (backsector->FloorSkyBox == pt) continue; - - // Check if the backside would map to the same visplane - if (backsector->FloorSkyBox != NULL) { fail = true; continue; } - if (backsector->floorplane != sector->ceilingplane) { fail = true; continue; } - if (backsector->lightlevel != sector->lightlevel) { fail = true; continue; } - if (backsector->GetTexture(sector_t::floor) != sector->GetTexture(sector_t::floor)) { fail = true; continue; } - if (backsector->GetXOffset(sector_t::floor) != sector->GetXOffset(sector_t::floor)) { fail = true; continue; } - if (backsector->GetYOffset(sector_t::floor) != sector->GetYOffset(sector_t::floor)) { fail = true; continue; } - if (backsector->GetXScale(sector_t::floor) != sector->GetXScale(sector_t::floor)) { fail = true; continue; } - if (backsector->GetYScale(sector_t::floor) != sector->GetYScale(sector_t::floor)) { fail = true; continue; } - if (backsector->GetAngle(sector_t::floor) != sector->GetAngle(sector_t::floor)) { fail = true; continue; } - if (SpreadFloorPortal(pt, alpha, backsector)) { fail = true; continue; } - } - if (!fail) - { - sector->FloorSkyBox = pt; - sector->SetAlpha(sector_t::floor, alpha); - } - return fail; -} - void P_SetupPortals() { TThinkerIterator it; @@ -974,51 +941,6 @@ void P_SetupPortals() pt->special1 = 0; points.Push(pt); } - - // Maps using undefined portal hacks may not benefit from portal optimizations. - if (ib_compatflags & BCOMPATF_BADPORTALS) return; - - for(unsigned i=0;ispecial1 == 0 && points[i]->Mate != NULL) - { - for(unsigned j=1;jspecial1 == 0 && points[j]->Mate != NULL && points[i]->GetClass() == points[j]->GetClass()) - { - fixed_t deltax1 = points[i]->Mate->x - points[i]->x; - fixed_t deltay1 = points[i]->Mate->y - points[i]->y; - fixed_t deltax2 = points[j]->Mate->x - points[j]->x; - fixed_t deltay2 = points[j]->Mate->y - points[j]->y; - - if (deltax1 == deltax2 && deltay1 == deltay2) - { - if (points[j]->Sector->FloorSkyBox == points[j]->Mate) - points[j]->Sector->FloorSkyBox = points[i]->Mate; - - if (points[j]->Sector->CeilingSkyBox == points[j]->Mate) - points[j]->Sector->CeilingSkyBox = points[i]->Mate; - - points[j]->special1 = 1; - } - } - } - } - } - validcount++; - // Some fudging to preserve an unintended 'portal bleeding' effect caused by incomplete checks in the rendering code. - // Due to the addition of linedef-based portals this effect no longer works. - for(int i=0;ibAlways && sectors[i].validcount != validcount) - { - SpreadCeilingPortal(barrier_cast(sectors[i].CeilingSkyBox), sectors[i].GetAlpha(sector_t::ceiling), §ors[i]); - } - if (sectors[i].FloorSkyBox != NULL && sectors[i].FloorSkyBox->bAlways && sectors[i].validcount != validcount) - { - SpreadFloorPortal(barrier_cast(sectors[i].FloorSkyBox), sectors[i].GetAlpha(sector_t::floor), §ors[i]); - } - } } inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t alpha) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 3fa6bdf7..99872001 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -584,7 +584,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl check->viewz == stacked_viewz && ( // headache inducing logic... :( - (ib_compatflags & BCOMPATF_BADPORTALS) || + (!(skybox->flags & MF_JUSTATTACKED)) || ( check->alpha == alpha && (alpha == 0 || // if alpha is > 0 everything needs to be checked diff --git a/src/sdl/crashcatcher.c b/src/sdl/crashcatcher.c index 7dc92840..53f3c6a6 100644 --- a/src/sdl/crashcatcher.c +++ b/src/sdl/crashcatcher.c @@ -97,8 +97,7 @@ static void gdb_info(pid_t pid) strcpy(respfile, "gdb-respfile-XXXXXX"); if((fd = mkstemp(respfile)) >= 0 && (f = fdopen(fd, "w"))) { - fprintf(f, "signal SIGCHLD\n" - "shell echo \"\"\n" + fprintf(f, "shell echo \"\"\n" "shell echo \"* Loaded Libraries\"\n" "info sharedlibrary\n" "shell echo \"\"\n" @@ -115,36 +114,8 @@ static void gdb_info(pid_t pid) "x/x $eip-3\nx/x $eip\n" "shell echo \"\"\n" "shell echo \"* Backtrace\"\n" - "backtrace full\n" -#if 0 /* This sorta works to print out the core, but is too slow and skips 0's.. */ - "shell echo \"\"\n" - "shell echo \"* Stack\"\n" - "set var $_sp = $esp\n" - "while $_sp <= $ebp - 12\n" - " printf \"%%08x: \", $_sp\n" - " set var $_i = $_sp\n" - " while $_i < $_sp + 16\n" - " printf \"%%08x \", {int} $_i\n" - " set $_i += 4\n" - " end\n" - " set var $_i = $_sp\n" - " while $_i < $_sp + 16\n" - " printf \"%%c\", {int} $_i\n" - " set ++$_i\n" - " end\n" - " set var $_sp += 16\n" - " printf \"\\n\"\n" - "end\n" - "if $_sp <= $ebp\n" - " printf \"%%08x: \", $esp\n" - " while $_sp <= $ebp\n" - " printf \"%%08x \", {int} $_i\n" - " set $_sp += 4\n" - " end\n" - " printf \"\\n\"\n" - "end\n" -#endif - "kill\n" + "thread apply all backtrace full\n" + "detach\n" "quit\n"); fclose(f); @@ -152,8 +123,8 @@ static void gdb_info(pid_t pid) snprintf(buf, sizeof(buf), "gdb --quiet --batch --command=%s --pid=%i", respfile, pid); printf("Executing: %s\n", buf); fflush(stdout); - system(buf); + system(buf); /* Clean up */ remove(respfile); } @@ -168,6 +139,7 @@ static void gdb_info(pid_t pid) printf("Could not create gdb command file\n"); } fflush(stdout); + kill(pid, SIGKILL); } @@ -267,8 +239,8 @@ static void crash_catcher(int signum, siginfo_t *siginfo, void *context) /* Make sure the effective uid is the real uid */ if (getuid() != geteuid()) { - fprintf(stderr, "%s (signal %i)\ngetuid() does not match geteuid().\n", sigdesc, signum); - _exit(-1); + raise(signum); + return; } #endif @@ -325,48 +297,18 @@ static void crash_catcher(int signum, siginfo_t *siginfo, void *context) } gdb_info(pid); -#if 0 /* Why won't this work? */ - if(ucontext) - { - unsigned char *ptr = ucontext->uc_stack.ss_sp; - size_t len; - - fprintf(f, "\n* Stack\n"); - for(len = ucontext->uc_stack.ss_size/4;len > 0; len -= 4) - { - fprintf(f, "0x%08x:", (int)ptr); - for(i = 0;i < ((len < 4) ? len : 4);++i) - { - fprintf(f, " %02x%02x%02x%02x", ptr[i*4 + 0], ptr[i*4 + 1], - ptr[i*4 + 2], ptr[i*4 + 3]); - } - fputc(' ', f); - fflush(f); - for(i = 0;i < ((len < 4) ? len : 4);++i) - { - fprintf(f, "%c", *(ptr++)); - fprintf(f, "%c", *(ptr++)); - fprintf(f, "%c", *(ptr++)); - fprintf(f, "%c", *(ptr++)); - } - fputc('\n', f); - fflush(f); - } - } -#endif - if(f != stderr) { fclose(f); #if (defined __unix__) if(cc_logfile) { - char buf[256]; + char buf[512]; snprintf(buf, sizeof(buf), - "if (which gxmessage > /dev/null 2>&1);" - "then gxmessage -buttons \"Damn it:0\" -center -title \"Very Fatal Error\" -file %s;" - "elif (which xmessage > /dev/null 2>&1);" - "then xmessage -buttons \"Damn it:0\" -center -file %s -geometry 600x400;" + "if (which gxmessage > /dev/null 2>&1) ; then\n" + " gxmessage -buttons \"Damn it:0\" -center -title \"Very Fatal Error\" -file %s\n" + "elif (which xmessage > /dev/null 2>&1) ; then\n" + " xmessage -buttons \"Damn it:0\" -center -file %s -geometry 600x400\n" "fi", cc_logfile, cc_logfile); system(buf); } @@ -376,8 +318,8 @@ static void crash_catcher(int signum, siginfo_t *siginfo, void *context) _exit(0); default: - /* Wait and let the child attach gdb */ - waitpid(dbg_pid, NULL, 0); + /* Wait indefinitely; we'll be killed when gdb is done */ + while(1) usleep(1000000); } } @@ -388,12 +330,13 @@ int cc_install_handlers(int num_signals, int *signals, const char *logfile, int memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = crash_catcher; - -#if !defined(__FreeBSD__) && !defined(__APPLE__) + +#ifdef SA_ONESHOT sa.sa_flags = SA_ONESHOT | SA_NODEFER | SA_SIGINFO; #else sa.sa_flags = SA_NODEFER | SA_SIGINFO; #endif + sigemptyset(&sa.sa_mask); cc_logfile = logfile; cc_user_info = user_info; diff --git a/src/svnrevision.h b/src/svnrevision.h index 21e3bcf4..7858b8ae 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3061" -#define ZD_SVN_REVISION_NUMBER 3061 +#define ZD_SVN_REVISION_STRING "3072" +#define ZD_SVN_REVISION_NUMBER 3072 diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index 7a94f244..efdf836a 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -26,7 +26,6 @@ IWad Game = "Doom" Config = "UrbanBrawl" Mapinfo = "mapinfo/urbanbrawl.txt" - Compatibility = "Portals" MustContain = "MAP01", "AD2LIB" BannerColors = "a8 a8 00", "a8 00 00" } From ab422b2dbd8123f25da9bce7f88f966f9a3dcc1d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 26 Dec 2010 10:04:02 +0000 Subject: [PATCH 74/82] - Update to ZDoom r3078: * Fixed: The player setup menu set the playerlass CVAR to the actual class name, not the display name as expected. * cleaned up p_ceiling.cpp * Added a new render style 'Shadow'. Essentially it's just a black translucent stencil with an alpha of 0.3. The purpose of this style is to be used as a software renderer approximation of GZDoom's spectre effect. * allow setting 'Shadow' as default fuzz effect * Changed CVAR conversion that strings 'false' and 'true' get evaluated as integers 0 and 1 respectively so that changing boolean CVARs to int does not destroy their values. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1144 b0f79afe-0144-0410-b225-9a4edf0717df --- src/c_cvars.cpp | 18 +- src/g_shared/a_artifacts.cpp | 2 - src/gl/scene/gl_sprite.cpp | 27 +- src/gl/scene/gl_spritelight.cpp | 2 +- src/menu/playermenu.cpp | 2 +- src/p_ceiling.cpp | 523 ++++++++++++++------------- src/p_mobj.cpp | 1 - src/p_spec.h | 7 +- src/r_blend.h | 4 + src/r_draw.cpp | 49 ++- src/r_things.cpp | 2 +- src/thingdef/thingdef_properties.cpp | 4 +- src/win32/fb_d3d9.cpp | 8 + wadsrc/static/menudef.txt | 9 +- 14 files changed, 388 insertions(+), 270 deletions(-) diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 3afdb7c8..51413c37 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -221,7 +221,16 @@ int FBaseCVar::ToInt (UCVarValue value, ECVarType type) #else case CVAR_Float: res = (int)value.Float; break; #endif - case CVAR_String: res = strtol (value.String, NULL, 0); break; + case CVAR_String: + { + if (stricmp (value.String, "true") == 0) + res = 1; + else if (stricmp (value.String, "false") == 0) + res = 0; + else + res = strtol (value.String, NULL, 0); + break; + } case CVAR_GUID: res = 0; break; default: res = 0; break; } @@ -444,7 +453,12 @@ UCVarValue FBaseCVar::FromString (const char *value, ECVarType type) break; case CVAR_Int: - ret.Int = strtol (value, NULL, 0); + if (stricmp (value, "true") == 0) + ret.Int = 1; + else if (stricmp (value, "false") == 0) + ret.Int = 0; + else + ret.Int = strtol (value, NULL, 0); break; case CVAR_Float: diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index c4f0f9d6..0370e226 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -36,8 +36,6 @@ static FRandom pr_torch ("Torch"); #define TIMEFREEZE_TICS ( 12 * TICRATE ) */ -EXTERN_CVAR (Bool, r_drawfuzz); - IMPLEMENT_CLASS (APowerup) // Powerup-Giver ------------------------------------------------------------- diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 3506b4ec..7a9d4b7b 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -67,6 +67,7 @@ CVAR(Float, gl_sclipfactor, 1.8, CVAR_ARCHIVE) CVAR(Int, gl_particles_style, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // 0 = square, 1 = round, 2 = smooth CVAR(Int, gl_billboard_mode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, gl_enhanced_nv_stealth, 3, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE) extern bool r_showviewer; EXTERN_CVAR (Float, transsouls) @@ -136,7 +137,7 @@ void GLSprite::Draw(int pass) gl_RenderState.AlphaFunc(GL_GEQUAL,trans*gl_mask_sprite_threshold); } - if (RenderStyle.BlendOp == STYLEOP_Fuzz) + if (RenderStyle.BlendOp == STYLEOP_Shadow) { float fuzzalpha=0.44f; float minalpha=0.1f; @@ -166,7 +167,7 @@ void GLSprite::Draw(int pass) additivefog = true; } } - if (RenderStyle.BlendOp!=STYLEOP_Fuzz) + if (RenderStyle.BlendOp!=STYLEOP_Shadow) { if (actor) { @@ -729,10 +730,26 @@ void GLSprite::Process(AActor* thing,sector_t * sector) ThingColor=0xffffff; RenderStyle = thing->RenderStyle; - RenderStyle.CheckFuzz(); trans = FIXED2FLOAT(thing->alpha); hw_styleflags = STYLEHW_Normal; + if (RenderStyle.BlendOp >= STYLEOP_Fuzz && RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub) + { + RenderStyle.CheckFuzz(); + if (RenderStyle.BlendOp == STYLEOP_Fuzz) + { + if (gl.shadermodel >= 4 && gl_fuzztype != 0) + { + // Todo: implement shader selection here + RenderStyle.BlendOp = STYLEOP_Shadow; // keep it valid for now + } + else + { + RenderStyle.BlendOp = STYLEOP_Shadow; + } + } + } + if (RenderStyle.Flags & STYLEF_TransSoulsAlpha) { trans = transsouls; @@ -742,7 +759,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) trans = 1.f; } - if (trans >= 1.f-FLT_EPSILON && RenderStyle.BlendOp != STYLEOP_Fuzz && ( + if (trans >= 1.f-FLT_EPSILON && RenderStyle.BlendOp != STYLEOP_Shadow && ( (RenderStyle.SrcAlpha == STYLEALPHA_One && RenderStyle.DestAlpha == STYLEALPHA_Zero) || (RenderStyle.SrcAlpha == STYLEALPHA_Src && RenderStyle.DestAlpha == STYLEALPHA_InvSrc) )) @@ -777,7 +794,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) if (enhancedvision && gl_enhanced_nightvision) { - if (RenderStyle.BlendOp == STYLEOP_Fuzz) + if (RenderStyle.BlendOp == STYLEOP_Shadow) { // enhanced vision makes them more visible! trans=0.5f; diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index f3086120..897c8361 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -263,7 +263,7 @@ int gl_SetSpriteLighting(FRenderStyle style, AActor *thing, int lightlevel, int cm->LightColor.r = cm->LightColor.g = cm->LightColor.b = gray; } - if (style.BlendOp == STYLEOP_Fuzz) + if (style.BlendOp == STYLEOP_Shadow) { gl.Color4f(0.2f * ThingColor.r / 255.f, 0.2f * ThingColor.g / 255.f, 0.2f * ThingColor.b / 255.f, (alpha = 0.33f)); diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 03300af1..de0292f7 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -912,7 +912,7 @@ void DPlayerMenu::ClassChanged (FListMenuItem *li) players[consoleplayer].userinfo.PlayerClass = sel-1; PickPlayerClass(); - cvar_set ("playerclass", sel == 0 ? "Random" : PlayerClass->Type->TypeName); + cvar_set ("playerclass", sel == 0 ? "Random" : PlayerClass->Type->Meta.GetMetaString (APMETA_DisplayName)); UpdateSkins(); UpdateColorsets(); diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index ec569735..3cb60bcb 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -30,9 +30,11 @@ #include "r_state.h" #include "gi.h" +//============================================================================ // // CEILINGS // +//============================================================================ IMPLEMENT_CLASS (DCeiling) @@ -40,6 +42,12 @@ DCeiling::DCeiling () { } +//============================================================================ +// +// +// +//============================================================================ + void DCeiling::Serialize (FArchive &arc) { Super::Serialize (arc); @@ -59,6 +67,12 @@ void DCeiling::Serialize (FArchive &arc) << m_Hexencrush; } +//============================================================================ +// +// +// +//============================================================================ + void DCeiling::PlayCeilingSound () { if (m_Sector->seqType >= 0) @@ -80,9 +94,12 @@ void DCeiling::PlayCeilingSound () } } +//============================================================================ // -// T_MoveCeiling +// DCeiling :: Tick // +//============================================================================ + void DCeiling::Tick () { EResult res; @@ -176,6 +193,12 @@ void DCeiling::Tick () } } +//============================================================================ +// +// +// +//============================================================================ + DCeiling::DCeiling (sector_t *sec) : DMovingCeiling (sec) { @@ -191,11 +214,258 @@ DCeiling::DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent) m_Silent = silent; } +//============================================================================ +// +// +// +//============================================================================ + +DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag, + fixed_t speed, fixed_t speed2, fixed_t height, + int crush, int silent, int change, bool hexencrush) +{ + fixed_t targheight = 0; // Silence, GCC + + // if ceiling already moving, don't start a second function on it + if (sec->PlaneMoving(sector_t::ceiling)) + { + return NULL; + } + + // new door thinker + DCeiling *ceiling = new DCeiling (sec, speed, speed2, silent); + vertex_t *spot = sec->lines[0]->v1; + + switch (type) + { + case ceilCrushAndRaise: + case ceilCrushRaiseAndStay: + ceiling->m_TopHeight = sec->ceilingplane.d; + case ceilLowerAndCrush: + case ceilLowerAndCrushDist: + targheight = sec->FindHighestFloorPoint (&spot); + if (type == ceilLowerAndCrush) + { + targheight += 8*FRACUNIT; + } + else if (type == ceilLowerAndCrushDist) + { + targheight += height; + } + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilRaiseToHighest: + targheight = sec->FindHighestCeilingSurrounding (&spot); + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + break; + + case ceilLowerByValue: + targheight = sec->ceilingplane.ZatPoint (spot) - height; + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilRaiseByValue: + targheight = sec->ceilingplane.ZatPoint (spot) + height; + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + break; + + case ceilMoveToValue: + { + int diff = height - sec->ceilingplane.ZatPoint (spot); + + targheight = height; + if (diff < 0) + { + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, height); + ceiling->m_Direction = -1; + } + else + { + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, height); + ceiling->m_Direction = 1; + } + } + break; + + case ceilLowerToHighestFloor: + targheight = sec->FindHighestFloorSurrounding (&spot); + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilRaiseToHighestFloor: + targheight = sec->FindHighestFloorSurrounding (&spot); + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + break; + + case ceilLowerInstant: + targheight = sec->ceilingplane.ZatPoint (spot) - height; + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + ceiling->m_Speed = height; + break; + + case ceilRaiseInstant: + targheight = sec->ceilingplane.ZatPoint (spot) + height; + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + ceiling->m_Speed = height; + break; + + case ceilLowerToNearest: + targheight = sec->FindNextLowestCeiling (&spot); + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilRaiseToNearest: + targheight = sec->FindNextHighestCeiling (&spot); + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + break; + + case ceilLowerToLowest: + targheight = sec->FindLowestCeilingSurrounding (&spot); + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilRaiseToLowest: + targheight = sec->FindLowestCeilingSurrounding (&spot); + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + break; + + case ceilLowerToFloor: + targheight = sec->FindHighestFloorPoint (&spot); + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilRaiseToFloor: // [RH] What's this for? + targheight = sec->FindHighestFloorPoint (&spot); + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + break; + + case ceilLowerToHighest: + targheight = sec->FindHighestCeilingSurrounding (&spot); + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilLowerByTexture: + targheight = sec->ceilingplane.ZatPoint (spot) - sec->FindShortestUpperAround (); + ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = -1; + break; + + case ceilRaiseByTexture: + targheight = sec->ceilingplane.ZatPoint (spot) + sec->FindShortestUpperAround (); + ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); + ceiling->m_Direction = 1; + break; + + default: + break; // Silence GCC + } + + ceiling->m_Tag = tag; + ceiling->m_Type = type; + ceiling->m_Crush = crush; + ceiling->m_Hexencrush = hexencrush; + + // Do not interpolate instant movement ceilings. + // Note for ZDoomGL: Check to make sure that you update the sector + // after the ceiling moves, because it hasn't actually moved yet. + fixed_t movedist; + + if (ceiling->m_Direction < 0) + { + movedist = sec->ceilingplane.d - ceiling->m_BottomHeight; + } + else + { + movedist = ceiling->m_TopHeight - sec->ceilingplane.d; + } + if (ceiling->m_Speed >= movedist) + { + ceiling->StopInterpolation(); + } + + // set texture/type change properties + if (change & 3) // if a texture change is indicated + { + if (change & 4) // if a numeric model change + { + sector_t *modelsec; + + //jff 5/23/98 find model with floor at target height if target + //is a floor type + modelsec = (/*type == ceilRaiseToHighest ||*/ + type == ceilRaiseToFloor || + /*type == ceilLowerToHighest ||*/ + type == ceilLowerToFloor) ? + sec->FindModelFloorSector (targheight) : + sec->FindModelCeilingSector (targheight); + if (modelsec != NULL) + { + ceiling->m_Texture = modelsec->GetTexture(sector_t::ceiling); + switch (change & 3) + { + case 1: // type is zeroed + ceiling->m_NewSpecial = 0; + ceiling->m_Type = genCeilingChg0; + break; + case 2: // type is copied + ceiling->m_NewSpecial = sec->special; + ceiling->m_Type = genCeilingChgT; + break; + case 3: // type is left alone + ceiling->m_Type = genCeilingChg; + break; + } + } + } + else if (line) // else if a trigger model change + { + ceiling->m_Texture = line->frontsector->GetTexture(sector_t::ceiling); + switch (change & 3) + { + case 1: // type is zeroed + ceiling->m_NewSpecial = 0; + ceiling->m_Type = genCeilingChg0; + break; + case 2: // type is copied + ceiling->m_NewSpecial = line->frontsector->special; + ceiling->m_Type = genCeilingChgT; + break; + case 3: // type is left alone + ceiling->m_Type = genCeilingChg; + break; + } + } + } + + ceiling->PlayCeilingSound (); + return ceiling; +} + +//============================================================================ // // EV_DoCeiling // Move a ceiling up/down and all around! // // [RH] Added tag, speed, speed2, height, crush, silent, change params +// +//============================================================================ + bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, int tag, fixed_t speed, fixed_t speed2, fixed_t height, int crush, int silent, int change, bool hexencrush) @@ -203,10 +473,6 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, int secnum; bool rtn; sector_t* sec; - DCeiling* ceiling; - bool manual = false; - fixed_t targheight = 0; // Silence, GCC - vertex_t* spot; rtn = false; @@ -216,11 +482,10 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, if (!line || !(sec = line->backsector)) return rtn; secnum = (int)(sec-sectors); - manual = true; // [RH] Hack to let manual crushers be retriggerable, too tag ^= secnum | 0x1000000; P_ActivateInStasisCeiling (tag); - goto manual_ceiling; + return !!DCeiling::Create(sec, type, line, tag, speed, speed2, height, crush, silent, change, hexencrush); } // Reactivate in-stasis ceilings...for certain types. @@ -234,252 +499,19 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, // affects all sectors with the same tag as the linedef while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { - sec = §ors[secnum]; -manual_ceiling: - // if ceiling already moving, don't start a second function on it - if (sec->PlaneMoving(sector_t::ceiling)) - { - if (!manual) - continue; - else - return false; - } - - // new door thinker - rtn = 1; - ceiling = new DCeiling (sec, speed, speed2, silent); - spot = sec->lines[0]->v1; - - switch (type) - { - case DCeiling::ceilCrushAndRaise: - case DCeiling::ceilCrushRaiseAndStay: - ceiling->m_TopHeight = sec->ceilingplane.d; - case DCeiling::ceilLowerAndCrush: - case DCeiling::ceilLowerAndCrushDist: - targheight = sec->FindHighestFloorPoint (&spot); - if (type == DCeiling::ceilLowerAndCrush) - { - targheight += 8*FRACUNIT; - } - else if (type == DCeiling::ceilLowerAndCrushDist) - { - targheight += height; - } - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilRaiseToHighest: - targheight = sec->FindHighestCeilingSurrounding (&spot); - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - break; - - case DCeiling::ceilLowerByValue: - targheight = sec->ceilingplane.ZatPoint (spot) - height; - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilRaiseByValue: - targheight = sec->ceilingplane.ZatPoint (spot) + height; - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - break; - - case DCeiling::ceilMoveToValue: - { - int diff = height - sec->ceilingplane.ZatPoint (spot); - - targheight = height; - if (diff < 0) - { - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, height); - ceiling->m_Direction = -1; - } - else - { - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, height); - ceiling->m_Direction = 1; - } - } - break; - - case DCeiling::ceilLowerToHighestFloor: - targheight = sec->FindHighestFloorSurrounding (&spot); - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilRaiseToHighestFloor: - targheight = sec->FindHighestFloorSurrounding (&spot); - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - break; - - case DCeiling::ceilLowerInstant: - targheight = sec->ceilingplane.ZatPoint (spot) - height; - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - ceiling->m_Speed = height; - break; - - case DCeiling::ceilRaiseInstant: - targheight = sec->ceilingplane.ZatPoint (spot) + height; - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - ceiling->m_Speed = height; - break; - - case DCeiling::ceilLowerToNearest: - targheight = sec->FindNextLowestCeiling (&spot); - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilRaiseToNearest: - targheight = sec->FindNextHighestCeiling (&spot); - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - break; - - case DCeiling::ceilLowerToLowest: - targheight = sec->FindLowestCeilingSurrounding (&spot); - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilRaiseToLowest: - targheight = sec->FindLowestCeilingSurrounding (&spot); - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - break; - - case DCeiling::ceilLowerToFloor: - targheight = sec->FindHighestFloorPoint (&spot); - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilRaiseToFloor: // [RH] What's this for? - targheight = sec->FindHighestFloorPoint (&spot); - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - break; - - case DCeiling::ceilLowerToHighest: - targheight = sec->FindHighestCeilingSurrounding (&spot); - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilLowerByTexture: - targheight = sec->ceilingplane.ZatPoint (spot) - sec->FindShortestUpperAround (); - ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = -1; - break; - - case DCeiling::ceilRaiseByTexture: - targheight = sec->ceilingplane.ZatPoint (spot) + sec->FindShortestUpperAround (); - ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); - ceiling->m_Direction = 1; - break; - - default: - break; // Silence GCC - } - - ceiling->m_Tag = tag; - ceiling->m_Type = type; - ceiling->m_Crush = crush; - ceiling->m_Hexencrush = hexencrush; - - // Do not interpolate instant movement ceilings. - // Note for ZDoomGL: Check to make sure that you update the sector - // after the ceiling moves, because it hasn't actually moved yet. - fixed_t movedist; - - if (ceiling->m_Direction < 0) - { - movedist = sec->ceilingplane.d - ceiling->m_BottomHeight; - } - else - { - movedist = ceiling->m_TopHeight - sec->ceilingplane.d; - } - if (ceiling->m_Speed >= movedist) - { - ceiling->StopInterpolation(); - } - - // set texture/type change properties - if (change & 3) // if a texture change is indicated - { - if (change & 4) // if a numeric model change - { - sector_t *modelsec; - - //jff 5/23/98 find model with floor at target height if target - //is a floor type - modelsec = (/*type == DCeiling::ceilRaiseToHighest ||*/ - type == DCeiling::ceilRaiseToFloor || - /*type == DCeiling::ceilLowerToHighest ||*/ - type == DCeiling::ceilLowerToFloor) ? - sec->FindModelFloorSector (targheight) : - sec->FindModelCeilingSector (targheight); - if (modelsec != NULL) - { - ceiling->m_Texture = modelsec->GetTexture(sector_t::ceiling); - switch (change & 3) - { - case 1: // type is zeroed - ceiling->m_NewSpecial = 0; - ceiling->m_Type = DCeiling::genCeilingChg0; - break; - case 2: // type is copied - ceiling->m_NewSpecial = sec->special; - ceiling->m_Type = DCeiling::genCeilingChgT; - break; - case 3: // type is left alone - ceiling->m_Type = DCeiling::genCeilingChg; - break; - } - } - } - else if (line) // else if a trigger model change - { - ceiling->m_Texture = line->frontsector->GetTexture(sector_t::ceiling); - switch (change & 3) - { - case 1: // type is zeroed - ceiling->m_NewSpecial = 0; - ceiling->m_Type = DCeiling::genCeilingChg0; - break; - case 2: // type is copied - ceiling->m_NewSpecial = line->frontsector->special; - ceiling->m_Type = DCeiling::genCeilingChgT; - break; - case 3: // type is left alone - ceiling->m_Type = DCeiling::genCeilingChg; - break; - } - } - } - - ceiling->PlayCeilingSound (); - - if (manual) - return rtn; + rtn |= !!DCeiling::Create(§ors[secnum], type, line, tag, speed, speed2, height, crush, silent, change, hexencrush); } return rtn; } +//============================================================================ // // Restart a ceiling that's in-stasis // [RH] Passed a tag instead of a line and rewritten to use a list // +//============================================================================ + void P_ActivateInStasisCeiling (int tag) { DCeiling *scan; @@ -495,11 +527,14 @@ void P_ActivateInStasisCeiling (int tag) } } +//============================================================================ // // EV_CeilingCrushStop // Stop a ceiling from crushing! // [RH] Passed a tag instead of a line and rewritten to use a list // +//============================================================================ + bool EV_CeilingCrushStop (int tag) { bool rtn = false; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index fbf6b28a..39a17bf7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -81,7 +81,6 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj); extern cycle_t BotSupportCycles; extern int BotWTG; -EXTERN_CVAR (Bool, r_drawfuzz); EXTERN_CVAR (Int, cl_rockettrails) // PRIVATE DATA DEFINITIONS ------------------------------------------------ diff --git a/src/p_spec.h b/src/p_spec.h index 21427626..8656e424 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -677,6 +677,10 @@ public: void Serialize (FArchive &arc); void Tick (); + static DCeiling *Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag, + fixed_t speed, fixed_t speed2, fixed_t height, + int crush, int silent, int change, bool hexencrush); + protected: ECeiling m_Type; fixed_t m_BottomHeight; @@ -702,9 +706,6 @@ protected: private: DCeiling (); - friend bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, - int tag, fixed_t speed, fixed_t speed2, fixed_t height, - int crush, int silent, int change, bool hexencrush); friend bool EV_CeilingCrushStop (int tag); friend void P_ActivateInStasisCeiling (int tag); }; diff --git a/src/r_blend.h b/src/r_blend.h index 132d0950..f9fefc9d 100644 --- a/src/r_blend.h +++ b/src/r_blend.h @@ -48,6 +48,7 @@ enum ERenderStyle STYLE_Add, // Draw additive STYLE_Shaded, // Treat patch data as alpha values for alphacolor STYLE_TranslucentStencil, + STYLE_Shadow, STYLE_Count }; @@ -63,6 +64,9 @@ enum ERenderOp STYLEOP_FuzzOrAdd, // Draw fuzzy or add, based on user preference STYLEOP_FuzzOrSub, // Draw fuzzy or subtract, based on user preference STYLEOP_FuzzOrRevSub, // Draw fuzzy or reverse subtract, based on user preference + + // special styles + STYLEOP_Shadow, }; enum ERenderAlpha diff --git a/src/r_draw.cpp b/src/r_draw.cpp index ba77ad2d..8fb3efe3 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -141,6 +141,7 @@ FRenderStyle LegacyRenderStyles[STYLE_Count] = /* STYLE_Add */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, 0 }}, /* STYLE_Shaded */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed }}, /* STYLE_TranslucentStencil */{{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed }}, + /* STYLE_Shadow */{{ STYLEOP_Shadow, 0, 0, 0 }}, }; #else FRenderStyle LegacyRenderStyles[STYLE_Count]; @@ -157,6 +158,7 @@ static const BYTE Styles[STYLE_Count * 4] = STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, 0, STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed, + STYLEOP_Shadow, 0, 0, 0 }; static struct LegacyInit @@ -2068,7 +2070,7 @@ void R_InitColumnDrawers () } // [RH] Choose column drawers in a single place -EXTERN_CVAR (Bool, r_drawfuzz) +EXTERN_CVAR (Int, r_drawfuzz) EXTERN_CVAR (Float, transsouls) CVAR (Bool, r_drawtrans, true, 0) @@ -2235,6 +2237,13 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, style.CheckFuzz(); + if (style.BlendOp == STYLEOP_Shadow) + { + style = LegacyRenderStyles[STYLE_TranslucentStencil]; + alpha = FRACUNIT*3/10; + color = 0; + } + if (style.Flags & STYLEF_TransSoulsAlpha) { alpha = fixed_t(transsouls * FRACUNIT); @@ -2390,16 +2399,42 @@ bool FRenderStyle::IsVisible(fixed_t alpha) const throw() void FRenderStyle::CheckFuzz() { - if (BlendOp == STYLEOP_FuzzOrAdd) + switch (BlendOp) { - BlendOp = (r_drawfuzz || !r_drawtrans) ? STYLEOP_Fuzz : STYLEOP_Add; + default: + return; + + case STYLEOP_FuzzOrAdd: + if (r_drawtrans && r_drawfuzz == 0) + { + BlendOp = STYLEOP_Add; + return; + } + break; + + case STYLEOP_FuzzOrSub: + if (r_drawtrans && r_drawfuzz == 0) + { + BlendOp = STYLEOP_Sub; + return; + } + break; + + case STYLEOP_FuzzOrRevSub: + if (r_drawtrans && r_drawfuzz == 0) + { + BlendOp = STYLEOP_RevSub; + return; + } + break; } - else if (BlendOp == STYLEOP_FuzzOrSub) + + if (r_drawfuzz == 2) { - BlendOp = (r_drawfuzz || !r_drawtrans) ? STYLEOP_Fuzz : STYLEOP_Sub; + BlendOp = STYLEOP_Shadow; } - else if (BlendOp == STYLEOP_FuzzOrRevSub) + else { - BlendOp = (r_drawfuzz || !r_drawtrans) ? STYLEOP_Fuzz : STYLEOP_RevSub; + BlendOp = STYLEOP_Fuzz; } } diff --git a/src/r_things.cpp b/src/r_things.cpp index be25d315..eff99e53 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -61,7 +61,7 @@ extern fixed_t globaluclip, globaldclip; #define BASEYCENTER (100) EXTERN_CVAR (Bool, st_scale) -CVAR (Bool, r_drawfuzz, true, CVAR_ARCHIVE) +CVAR (Int, r_drawfuzz, 1, CVAR_ARCHIVE) // diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index d41d7989..ad7bde72 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -601,11 +601,11 @@ DEFINE_PROPERTY(renderstyle, S, Actor) { PROP_STRING_PARM(str, 0); static const char * renderstyles[]={ - "NONE","NORMAL","FUZZY","SOULTRANS","OPTFUZZY","STENCIL","TRANSLUCENT", "ADD","SHADED", NULL}; + "NONE","NORMAL","FUZZY","SOULTRANS","OPTFUZZY","STENCIL","TRANSLUCENT", "ADD", "SHADED", "SHADOW", NULL}; static const int renderstyle_values[]={ STYLE_None, STYLE_Normal, STYLE_Fuzzy, STYLE_SoulTrans, STYLE_OptFuzzy, - STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded}; + STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded, STYLE_Shadow}; // make this work for old style decorations, too. if (!strnicmp(str, "style_", 6)) str+=6; diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index cc036d54..b0f25bbe 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -3677,6 +3677,14 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & alpha = clamp (parms.alpha, 0, FRACUNIT) / 65536.f; } + style.CheckFuzz(); + if (style.BlendOp == STYLEOP_Shadow) + { + style = LegacyRenderStyles[STYLE_TranslucentStencil]; + alpha = 0.3f; + parms.fillcolor = 0; + } + // FIXME: Fuzz effect is not written if (style.BlendOp == STYLEOP_FuzzOrAdd || style.BlendOp == STYLEOP_Fuzz) { diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 243029f1..4ddf8dfb 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -640,6 +640,13 @@ OptionValue Contrast 2.0, "Smooth" } +OptionValue Fuzziness +{ + 0.0, "Translucent" + 1.0, "Fuzz" + 2.0, "Shadow" +} + OptionMenu "VideoOptions" { Title "DISPLAY OPTIONS" @@ -662,7 +669,7 @@ OptionMenu "VideoOptions" } Option "Stretch short skies", "r_stretchsky", "OnOff" - Option "Use fuzz effect", "r_drawfuzz", "YesNo" + Option "Use fuzz effect", "r_drawfuzz", "Fuzziness" Slider "Lost Soul translucency", "transsouls", 0.25, 1.0, 0.05, 2 Option "Use fake contrast", "r_fakecontrast", "Contrast" Option "Rocket Trails", "cl_rockettrails", "RocketTrailTypes" From 273e124b9276bd3d0e8887035707633e4578fc96 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 26 Dec 2010 13:58:12 +0000 Subject: [PATCH 75/82] - fixed renderstyle setup for shadow style. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1145 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/renderer/gl_lightdata.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 08c9ac8a..95293aa6 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -150,11 +150,12 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend int *tm, int *sb, int *db, int *be) { static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }; - static int renderops[] = { 0, GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, -1, -1, -1, -1}; + static int renderops[] = { 0, GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 }; int srcblend = blendstyles[style.SrcAlpha&3]; int dstblend = blendstyles[style.DestAlpha&3]; - int blendequation = renderops[style.BlendOp&7]; + int blendequation = renderops[style.BlendOp&15]; int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE; if (style.Flags & STYLEF_ColorIsFixed) From b9d326762f0c6992d6c5be595244303b04ce3eec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 26 Dec 2010 14:25:24 +0000 Subject: [PATCH 76/82] - added Evil Space Tomato's fuzz shaders as optional fuzz types. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1146 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/scene/gl_sprite.cpp | 14 ++++++++--- src/gl/scene/gl_wall.h | 1 + src/gl/shaders/gl_shader.cpp | 5 ++++ src/gl/textures/gl_material.cpp | 14 +++++++---- src/gl/textures/gl_material.h | 4 ++-- wadsrc/static/menudef.z | 13 +++++++++- wadsrc/static/shaders/glsl/fuzz_jagged.fp | 24 +++++++++++++++++++ wadsrc/static/shaders/glsl/fuzz_smooth.fp | 21 ++++++++++++++++ .../shaders/glsl/fuzz_smoothtranslucent.fp | 18 ++++++++++++++ wadsrc/static/shaders/glsl/fuzz_standard.fp | 24 +++++++++++++++++++ wadsrc/static/shaders/glsl/fuzz_swirly.fp | 21 ++++++++++++++++ 11 files changed, 148 insertions(+), 11 deletions(-) create mode 100644 wadsrc/static/shaders/glsl/fuzz_jagged.fp create mode 100644 wadsrc/static/shaders/glsl/fuzz_smooth.fp create mode 100644 wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp create mode 100644 wadsrc/static/shaders/glsl/fuzz_standard.fp create mode 100644 wadsrc/static/shaders/glsl/fuzz_swirly.fp diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 7a9d4b7b..3b309caf 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -67,7 +67,10 @@ CVAR(Float, gl_sclipfactor, 1.8, CVAR_ARCHIVE) CVAR(Int, gl_particles_style, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // 0 = square, 1 = round, 2 = smooth CVAR(Int, gl_billboard_mode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, gl_enhanced_nv_stealth, 3, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE) +CUSTOM_CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE) +{ + if (self < 0 || self > 5) self = 0; +} extern bool r_showviewer; EXTERN_CVAR (Float, transsouls) @@ -204,7 +207,7 @@ void GLSprite::Draw(int pass) gl_SetFog(foglevel, rel, &Colormap, additivefog); - if (gltexture) gltexture->BindPatch(Colormap.colormap,translation); + if (gltexture) gltexture->BindPatch(Colormap.colormap, translation, OverrideShader); else if (!modelframe) gl_RenderState.EnableTexture(false); if (!modelframe) @@ -730,6 +733,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) ThingColor=0xffffff; RenderStyle = thing->RenderStyle; + OverrideShader = 0; trans = FIXED2FLOAT(thing->alpha); hw_styleflags = STYLEHW_Normal; @@ -741,7 +745,10 @@ void GLSprite::Process(AActor* thing,sector_t * sector) if (gl.shadermodel >= 4 && gl_fuzztype != 0) { // Todo: implement shader selection here - RenderStyle.BlendOp = STYLEOP_Shadow; // keep it valid for now + RenderStyle = LegacyRenderStyles[STYLE_Translucent]; + OverrideShader = gl_fuzztype + 4; + trans = 0.99f; // trans may not be 1 here + hw_styleflags |= STYLEHW_NoAlphaTest; } else { @@ -885,6 +892,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s trans=particle->trans/255.0f; RenderStyle = STYLE_Translucent; + OverrideShader = 0; ThingColor = GPalette.BaseColors[particle->color]; ThingColor.a=0; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 58b81d68..0aab09f4 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -305,6 +305,7 @@ public: FColormap Colormap; FSpriteModelFrame * modelframe; FRenderStyle RenderStyle; + int OverrideShader; int translation; int index; diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index ded277cf..e7ff00a8 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -389,6 +389,11 @@ static const FDefaultShader defaultshaders[]= {"Warp 2", "shaders/glsl/func_warp2.fp"}, {"Brightmap","shaders/glsl/func_brightmap.fp"}, {"No Texture", "shaders/glsl/func_notexture.fp"}, + {"Basic Fuzz", "shaders/glsl/fuzz_standard.fp"}, + {"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp"}, + {"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp"}, + {"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp"}, + {"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp"}, {NULL,NULL} }; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index dbd69420..64bed441 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -834,10 +834,10 @@ outl: // //=========================================================================== -void FMaterial::Bind(int cm, int clampmode, int translation) +void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader) { int usebright = false; - int shaderindex = mShaderIndex; + int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT; @@ -848,7 +848,7 @@ void FMaterial::Bind(int cm, int clampmode, int translation) else clampmode = 4; const FHardwareTexture *gltexture = mBaseLayer->Bind(0, cm, clampmode, translation, allowhires? tex:NULL, softwarewarp); - if (gltexture != NULL && shaderindex > 0) + if (gltexture != NULL && shaderindex > 0 && overrideshader == 0) { for(unsigned i=0;i 0) + { + __asm nop + } int usebright = false; - int shaderindex = mShaderIndex; + int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed); diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index f5d29d27..f1402173 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -134,8 +134,8 @@ public: return !!mBaseLayer->tex->bMasked; } - void Bind(int cm, int clamp=0, int translation=0); - void BindPatch(int cm, int translation=0); + void Bind(int cm, int clamp = 0, int translation = 0, int overrideshader = 0); + void BindPatch(int cm, int translation = 0, int overrideshader = 0); unsigned char * CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand = false, bool allowhires=true) const { diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index 53ff7f61..16f07d39 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -124,6 +124,16 @@ OptionValue "FogMode" 2, "Radial" } +OptionValue "FuzzStyle" +{ + 0, "Shadow" + 1, "Pixel fuzz" + 2, "Smooth fuzz" + 3, "Swirly fuzz" + 4, "Translucent fuzz" + //5, "Jagged fuzz" I can't see any difference between this and 4 so it's disabled for now. +} + OptionMenu "GLTextureGLOptions" { Title "TEXTURE OPTIONS" @@ -166,6 +176,7 @@ OptionMenu "GLPrefOptions" Option "Force brightness in fog", gl_spritebrightfog, "OnOff" Option "Adjust sprite clipping", gl_spriteclip, "SpriteclipModes" Option "Smooth sprite edges", gl_sprite_blend, "OnOff" + Option "Fuzz Style", gl_fuzztype, "FuzzStyle" Option "Sprite billboard", gl_billboard_mode, "BillboardModes" Option "Particle style", gl_particles_style, "Particles" Slider "Ambient light level", gl_light_ambient, 1.0, 255.0, 5.0 @@ -216,7 +227,7 @@ OptionMenu "VideoOptions" } Option "Stretch short skies", "r_stretchsky", "OnOff" - Option "Use fuzz effect", "r_drawfuzz", "YesNo" + Option "Use fuzz effect", "r_drawfuzz", "Fuzziness" Slider "Lost Soul translucency", "transsouls", 0.25, 1.0, 0.05, 2 Option "Use fake contrast", "r_fakecontrast", "Contrast" Option "Rocket Trails", "cl_rockettrails", "RocketTrailTypes" diff --git a/wadsrc/static/shaders/glsl/fuzz_jagged.fp b/wadsrc/static/shaders/glsl/fuzz_jagged.fp new file mode 100644 index 00000000..7c3bd004 --- /dev/null +++ b/wadsrc/static/shaders/glsl/fuzz_jagged.fp @@ -0,0 +1,24 @@ +uniform float timer; + +vec4 Process(vec4 color) +{ + vec2 texCoord = gl_TexCoord[0].st; + + vec2 texSplat; + const float pi = 3.14159265358979323846; + texSplat.x = texCoord.x + mod(sin(pi * 2.0 * (texCoord.y + timer * 2.0)),0.1) * 0.1; + texSplat.y = texCoord.y + mod(cos(pi * 2.0 * (texCoord.x + timer * 2.0)),0.1) * 0.1; + + vec4 basicColor = getTexel(texSplat) * color; + + float texX = sin(texCoord.x * 100 + timer*5); + float texY = cos(texCoord.x * 100 + timer*5); + float vX = (texX/texY)*21.0f; + float vY = (texY/texX)*13.0f; + + float test = mod(timer*2.0f+(vX + vY), 0.5f); + + basicColor.a = basicColor.a * test; + + return basicColor; +} diff --git a/wadsrc/static/shaders/glsl/fuzz_smooth.fp b/wadsrc/static/shaders/glsl/fuzz_smooth.fp new file mode 100644 index 00000000..5ae16e2f --- /dev/null +++ b/wadsrc/static/shaders/glsl/fuzz_smooth.fp @@ -0,0 +1,21 @@ +uniform float timer; + +vec4 Process(vec4 color) +{ + vec2 texCoord = gl_TexCoord[0].st; + vec4 basicColor = getTexel(texCoord) * color; + + float texX = texCoord.x / 3.0f + 0.66f; + float texY = 0.34 - texCoord.y / 3.0f; + float vX = (texX/texY)*21.0f; + float vY = (texY/texX)*13.0f; + + + float test = mod(timer*2.0f+(vX + vY), 0.5f); + +// float test = mod(timer*2.0f+((texCoord.x/texCoord.y*abs(basicColor.r + basicColor.g/2))*21.0f + (texCoord.y/texCoord.x*abs(basicColor.b + basicColor.g/2))*13.0f), 0.3f); + basicColor.a = basicColor.a * test; + + basicColor.r = basicColor.g = basicColor.b = 0.0f;//(basicColor.r + basicColor.g + basicColor.b) / 3.0f; + return basicColor; +} diff --git a/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp new file mode 100644 index 00000000..9c723b84 --- /dev/null +++ b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp @@ -0,0 +1,18 @@ +uniform float timer; + +vec4 Process(vec4 color) +{ + vec2 texCoord = gl_TexCoord[0].st; + vec4 basicColor = getTexel(texCoord) * color; + + float texX = sin(texCoord.x * 100 + timer*5); + float texY = cos(texCoord.x * 100 + timer*5); + float vX = (texX/texY)*21.0f; + float vY = (texY/texX)*13.0f; + + float test = mod(timer*2.0f+(vX + vY), 0.5f); + + basicColor.a = basicColor.a * test; + + return basicColor; +} diff --git a/wadsrc/static/shaders/glsl/fuzz_standard.fp b/wadsrc/static/shaders/glsl/fuzz_standard.fp new file mode 100644 index 00000000..98cc75a1 --- /dev/null +++ b/wadsrc/static/shaders/glsl/fuzz_standard.fp @@ -0,0 +1,24 @@ +uniform float timer; + +vec4 Process(vec4 color) +{ + vec2 texCoord = gl_TexCoord[0].st; + vec4 basicColor = getTexel(texCoord) * color; + + texCoord.x = int(texCoord.x * 128) / 128.0f; + texCoord.y = int(texCoord.y * 128) / 128.0f; + + float texX = texCoord.x / 3.0f + 0.66f; + float texY = 0.34 - texCoord.y / 3.0f; + float vX = (texX/texY)*21.0f; + float vY = (texY/texX)*13.0f; + + + float test = mod(timer*2.0f+(vX + vY), 0.5f); + +// float test = mod(timer*2.0f+((texCoord.x/texCoord.y*abs(basicColor.r + basicColor.g/2))*21.0f + (texCoord.y/texCoord.x*abs(basicColor.b + basicColor.g/2))*13.0f), 0.3f); + basicColor.a = basicColor.a * test; + + basicColor.r = basicColor.g = basicColor.b = 0.0f;//(basicColor.r + basicColor.g + basicColor.b) / 3.0f; + return basicColor; +} diff --git a/wadsrc/static/shaders/glsl/fuzz_swirly.fp b/wadsrc/static/shaders/glsl/fuzz_swirly.fp new file mode 100644 index 00000000..61cf6dee --- /dev/null +++ b/wadsrc/static/shaders/glsl/fuzz_swirly.fp @@ -0,0 +1,21 @@ +uniform float timer; + +vec4 Process(vec4 color) +{ + vec2 texCoord = gl_TexCoord[0].st; + vec4 basicColor = getTexel(texCoord) * color; + + float texX = sin(texCoord.x * 100 + timer*5); + float texY = cos(texCoord.x * 100 + timer*5); + float vX = (texX/texY)*21.0f; + float vY = (texY/texX)*13.0f; + + + float test = mod(timer*2.0f+(vX + vY), 0.5f); + +// float test = mod(timer*2.0f+((texCoord.x/texCoord.y*abs(basicColor.r + basicColor.g/2))*21.0f + (texCoord.y/texCoord.x*abs(basicColor.b + basicColor.g/2))*13.0f), 0.3f); + basicColor.a = basicColor.a * test; + + basicColor.r = basicColor.g = basicColor.b = 0.0f;//(basicColor.r + basicColor.g + basicColor.b) / 3.0f; + return basicColor; +} From 7a125f6312bc7a31072e5c1396addee152910fb6 Mon Sep 17 00:00:00 2001 From: gez Date: Tue, 28 Dec 2010 08:17:48 +0000 Subject: [PATCH 77/82] * Updated to ZDoom r3080: - Added a new 'playertype' command for SBARINFO that checks by class type not display name. - Fixed: Status bar display for Hexen's fourth weapons only worked when they were obtained by picking up the weapon pieces. * Added attribution to fuzz shader code. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1147 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_shared/sbarinfo_commands.cpp | 57 ++++++++- src/p_doors.cpp | 119 ++++++++++++------ src/svnrevision.h | 4 +- wadsrc/static/sbarinfo/hexen.txt | 91 ++++++-------- wadsrc/static/shaders/glsl/fuzz_jagged.fp | 1 + wadsrc/static/shaders/glsl/fuzz_smooth.fp | 1 + .../shaders/glsl/fuzz_smoothtranslucent.fp | 1 + wadsrc/static/shaders/glsl/fuzz_standard.fp | 1 + wadsrc/static/shaders/glsl/fuzz_swirly.fp | 1 + 9 files changed, 185 insertions(+), 91 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index fcc5a6e1..c63b009e 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -2660,6 +2660,58 @@ class CommandPlayerClass : public SBarInfoCommandFlowControl //////////////////////////////////////////////////////////////////////////////// +class CommandPlayerType : public SBarInfoCommandFlowControl +{ + public: + CommandPlayerType(SBarInfo *script) : SBarInfoCommandFlowControl(script) + { + } + + void Parse(FScanner &sc, bool fullScreenOffsets) + { + sc.MustGetToken(TK_Identifier); + do + { + bool foundClass = false; + const PClass *cls = PClass::FindClass(sc.String); + if (cls != NULL) + { + foundClass = true; + classes.Push(cls); + } + /* + if(!foundClass) + sc.ScriptError("Unkown PlayerClass '%s'.", sc.String); + */ + if(!sc.CheckToken(',')) + break; + } + while(sc.CheckToken(TK_Identifier)); + SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets); + } + void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) + { + SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); + + if(statusBar->CPlayer->cls == NULL) + return; //No class so we can not continue + + for(unsigned int i = 0;i < classes.Size();i++) + { + if (statusBar->CPlayer->cls->IsDescendantOf(classes[i])) + { + SetTruth(true, block, statusBar); + return; + } + } + SetTruth(false, block, statusBar); + } + protected: + TArray classes; +}; + +//////////////////////////////////////////////////////////////////////////////// + class CommandHasWeaponPiece : public SBarInfoCommandFlowControl { public: @@ -3082,7 +3134,7 @@ static const char *SBarInfoCommandNames[] = "drawmugshot", "drawselectedinventory", "drawinventorybar", "drawbar", "drawgem", "drawshader", "drawstring", "drawkeybar", - "gamemode", "playerclass", "aspectratio", + "gamemode", "playerclass", "playertype", "aspectratio", "isselected", "usesammo", "usessecondaryammo", "hasweaponpiece", "inventorybarnotvisible", "weaponammo", "ininventory", "alpha", @@ -3095,7 +3147,7 @@ enum SBarInfoCommands SBARINFO_DRAWMUGSHOT, SBARINFO_DRAWSELECTEDINVENTORY, SBARINFO_DRAWINVENTORYBAR, SBARINFO_DRAWBAR, SBARINFO_DRAWGEM, SBARINFO_DRAWSHADER, SBARINFO_DRAWSTRING, SBARINFO_DRAWKEYBAR, - SBARINFO_GAMEMODE, SBARINFO_PLAYERCLASS, SBARINFO_ASPECTRATIO, + SBARINFO_GAMEMODE, SBARINFO_PLAYERCLASS, SBARINFO_PLAYERTYPE, SBARINFO_ASPECTRATIO, SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO, SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE, SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, @@ -3126,6 +3178,7 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc) case SBARINFO_ASPECTRATIO: return new CommandAspectRatio(script); case SBARINFO_ISSELECTED: return new CommandIsSelected(script); case SBARINFO_PLAYERCLASS: return new CommandPlayerClass(script); + case SBARINFO_PLAYERTYPE: return new CommandPlayerType(script); case SBARINFO_HASWEAPONPIECE: return new CommandHasWeaponPiece(script); case SBARINFO_WEAPONAMMO: return new CommandWeaponAmmo(script); case SBARINFO_ININVENTORY: return new CommandInInventory(script); diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 557928c5..c01abab6 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -36,6 +36,12 @@ #include "sc_man.h" #include "cmdlib.h" +//============================================================================ +// +// VERTICAL DOORS +// +//============================================================================ + IMPLEMENT_CLASS (DDoor) DDoor::DDoor () @@ -55,14 +61,12 @@ void DDoor::Serialize (FArchive &arc) << m_LightTag; } - -// -// VERTICAL DOORS -// - +//============================================================================ // // T_VerticalDoor // +//============================================================================ + void DDoor::Tick () { EResult res; @@ -215,7 +219,12 @@ void DDoor::Tick () } } +//============================================================================ +// // [RH] DoorSound: Plays door sound depending on direction and speed +// +//============================================================================ + void DDoor::DoorSound (bool raise) const { int choice; @@ -309,10 +318,12 @@ DDoor::DDoor (sector_t *sector) { } -// [RH] Merged EV_VerticalDoor and EV_DoLockedDoor into EV_DoDoor -// and made them more general to support the new specials. - +//============================================================================ +// // [RH] SpawnDoor: Helper function for EV_DoDoor +// +//============================================================================ + DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag) : DMovingCeiling (sec), m_Type (type), m_Speed (speed), m_TopWait (delay), m_LightTag (lightTag) @@ -371,6 +382,13 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa m_OldFloorDist = sec->floorplane.d; } +//============================================================================ +// +// [RH] Merged EV_VerticalDoor and EV_DoLockedDoor into EV_DoDoor +// and made them more general to support the new specials. +// +//============================================================================ + bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, int tag, int speed, int delay, int lock, int lightTag) { @@ -464,10 +482,12 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, return rtn; } - +//============================================================================ // // Spawn a door that closes after 30 seconds // +//============================================================================ + void P_SpawnDoorCloseIn30 (sector_t *sec) { fixed_t height; @@ -487,18 +507,56 @@ void P_SpawnDoorCloseIn30 (sector_t *sec) door->m_LightTag = 0; } +//============================================================================ // // Spawn a door that opens after 5 minutes // +//============================================================================ + void P_SpawnDoorRaiseIn5Mins (sector_t *sec) { sec->special = 0; new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0); } -// EV_SlidingDoor : slide a door horizontally -// (animate midtexture, then set noblocking line) + +//============================================================================ // +// animated doors +// +//============================================================================ + +IMPLEMENT_CLASS (DAnimatedDoor) + +DAnimatedDoor::DAnimatedDoor () +{ +} + +DAnimatedDoor::DAnimatedDoor (sector_t *sec) + : DMovingCeiling (sec) +{ +} + +void DAnimatedDoor::Serialize (FArchive &arc) +{ + Super::Serialize (arc); + + arc << m_Line1 << m_Line2 + << m_Frame + << m_Timer + << m_BotDist + << m_Status + << m_Speed + << m_Delay + << m_DoorAnim + << m_SetBlocking1 << m_SetBlocking2; +} + +//============================================================================ +// +// Starts a closing action on an animated door +// +//============================================================================ bool DAnimatedDoor::StartClosing () { @@ -528,6 +586,12 @@ bool DAnimatedDoor::StartClosing () return true; } +//============================================================================ +// +// +// +//============================================================================ + void DAnimatedDoor::Tick () { if (m_DoorAnim == NULL) @@ -624,31 +688,11 @@ void DAnimatedDoor::Tick () } } -IMPLEMENT_CLASS (DAnimatedDoor) - -DAnimatedDoor::DAnimatedDoor () -{ -} - -DAnimatedDoor::DAnimatedDoor (sector_t *sec) - : DMovingCeiling (sec) -{ -} - -void DAnimatedDoor::Serialize (FArchive &arc) -{ - Super::Serialize (arc); - - arc << m_Line1 << m_Line2 - << m_Frame - << m_Timer - << m_BotDist - << m_Status - << m_Speed - << m_Delay - << m_DoorAnim - << m_SetBlocking1 << m_SetBlocking2; -} +//============================================================================ +// +// +// +//============================================================================ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim) : DMovingCeiling (sec) @@ -706,7 +750,8 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, //============================================================================ // -// EV_SlidingDoor +// EV_SlidingDoor : slide a door horizontally +// (animate midtexture, then set noblocking line) // //============================================================================ diff --git a/src/svnrevision.h b/src/svnrevision.h index 7858b8ae..4d49adb0 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3072" -#define ZD_SVN_REVISION_NUMBER 3072 +#define ZD_SVN_REVISION_STRING "3080" +#define ZD_SVN_REVISION_NUMBER 3080 diff --git a/wadsrc/static/sbarinfo/hexen.txt b/wadsrc/static/sbarinfo/hexen.txt index 635cb650..e7a4c6c4 100644 --- a/wadsrc/static/sbarinfo/hexen.txt +++ b/wadsrc/static/sbarinfo/hexen.txt @@ -114,29 +114,26 @@ statusbar Normal drawimage "ARMCLS", 255, 178; drawnumber 2, HUDFONT_RAVEN, untranslated, armorclass, 275, 176, 1; - playerclass Cleric + playertype ClericPlayer { drawimage "WPSLOT1", 190, 162; - hasweaponpiece CWeapWraithverge, 1 + ininventory CWeapWraithverge { - drawimage "WPIECEC1", 190, 162; + drawimage "WPFULL1", 190, 162; } - hasweaponpiece CWeapWraithverge, 2 - { - drawimage "WPIECEC2", 212, 162; - } - hasweaponpiece CWeapWraithverge, 3 - { - drawimage "WPIECEC3", 225, 162; - } - hasweaponpiece CWeapWraithverge, 1 + else { + hasweaponpiece CWeapWraithverge, 1 + { + drawimage "WPIECEC1", 190, 162; + } hasweaponpiece CWeapWraithverge, 2 { - hasweaponpiece CWeapWraithverge, 3 - { - drawimage "WPFULL1", 190, 162; - } + drawimage "WPIECEC2", 212, 162; + } + hasweaponpiece CWeapWraithverge, 3 + { + drawimage "WPIECEC3", 225, 162; } } @@ -145,29 +142,26 @@ statusbar Normal else drawgem translatable, interpolate(6), "CHAIN2", "LIFEGMC2", -23, 49, 15, 30, 193; } - else playerclass Mage + else playertype MagePlayer { drawimage "WPSLOT2", 190, 162; - hasweaponpiece MWeapBloodscourge, 1 + ininventory MWeapBloodscourge { - drawimage "WPIECEM1", 190, 162; + drawimage "WPFULL2", 190, 162; } - hasweaponpiece MWeapBloodscourge, 2 - { - drawimage "WPIECEM2", 205, 162; - } - hasweaponpiece MWeapBloodscourge, 3 - { - drawimage "WPIECEM3", 224, 162; - } - hasweaponpiece MWeapBloodscourge, 1 + else { + hasweaponpiece MWeapBloodscourge, 1 + { + drawimage "WPIECEM1", 190, 162; + } hasweaponpiece MWeapBloodscourge, 2 { - hasweaponpiece MWeapBloodscourge, 3 - { - drawimage "WPFULL2", 190, 162; - } + drawimage "WPIECEM2", 205, 162; + } + hasweaponpiece MWeapBloodscourge, 3 + { + drawimage "WPIECEM3", 224, 162; } } @@ -179,26 +173,23 @@ statusbar Normal else { drawimage "WPSLOT0", 190, 162; - hasweaponpiece FWeapQuietus, 1 + ininventory FWeapQuietus { - drawimage "WPIECEF1", 190, 162; + drawimage "WPFULL0", 190, 162; } - hasweaponpiece FWeapQuietus, 2 - { - drawimage "WPIECEF2", 225, 162; - } - hasweaponpiece FWeapQuietus, 3 - { - drawimage "WPIECEF3", 234, 162; - } - hasweaponpiece FWeapQuietus, 1 + else { + hasweaponpiece FWeapQuietus, 1 + { + drawimage "WPIECEF1", 190, 162; + } hasweaponpiece FWeapQuietus, 2 { - hasweaponpiece FWeapQuietus, 3 - { - drawimage "WPFULL0", 190, 162; - } + drawimage "WPIECEF2", 225, 162; + } + hasweaponpiece FWeapQuietus, 3 + { + drawimage "WPIECEF3", 234, 162; } } @@ -222,21 +213,21 @@ statusbar Automap drawimage hexenarmor amulet, "ARMSLOT4", 243, 164; // Also draw the life gem here - playerclass Fighter + playertype FighterPlayer { gamemode singleplayer drawgem interpolate(6), "CHAIN", "LIFEGMF2", -23, 49, 15, 30, 193; else drawgem translatable, interpolate(6), "CHAIN", "LIFEGMF2", -23, 49, 15, 30, 193; } - else playerclass Cleric + else playertype ClericPlayer { gamemode singleplayer drawgem interpolate(6), "CHAIN2", "LIFEGMC2", -23, 49, 15, 30, 193; else drawgem translatable, interpolate(6), "CHAIN2", "LIFEGMC2", -23, 49, 15, 30, 193; } - else playerclass Mage + else playertype MagePlayer { gamemode singleplayer drawgem interpolate(6), "CHAIN3", "LIFEGMM2", -23, 49, 15, 30, 193; diff --git a/wadsrc/static/shaders/glsl/fuzz_jagged.fp b/wadsrc/static/shaders/glsl/fuzz_jagged.fp index 7c3bd004..6f44a012 100644 --- a/wadsrc/static/shaders/glsl/fuzz_jagged.fp +++ b/wadsrc/static/shaders/glsl/fuzz_jagged.fp @@ -1,3 +1,4 @@ +//created by Evil Space Tomato uniform float timer; vec4 Process(vec4 color) diff --git a/wadsrc/static/shaders/glsl/fuzz_smooth.fp b/wadsrc/static/shaders/glsl/fuzz_smooth.fp index 5ae16e2f..2cfb9157 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smooth.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smooth.fp @@ -1,3 +1,4 @@ +//created by Evil Space Tomato uniform float timer; vec4 Process(vec4 color) diff --git a/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp index 9c723b84..eca5601f 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp @@ -1,3 +1,4 @@ +//created by Evil Space Tomato uniform float timer; vec4 Process(vec4 color) diff --git a/wadsrc/static/shaders/glsl/fuzz_standard.fp b/wadsrc/static/shaders/glsl/fuzz_standard.fp index 98cc75a1..315ce842 100644 --- a/wadsrc/static/shaders/glsl/fuzz_standard.fp +++ b/wadsrc/static/shaders/glsl/fuzz_standard.fp @@ -1,3 +1,4 @@ +//created by Evil Space Tomato uniform float timer; vec4 Process(vec4 color) diff --git a/wadsrc/static/shaders/glsl/fuzz_swirly.fp b/wadsrc/static/shaders/glsl/fuzz_swirly.fp index 61cf6dee..7c75d7ad 100644 --- a/wadsrc/static/shaders/glsl/fuzz_swirly.fp +++ b/wadsrc/static/shaders/glsl/fuzz_swirly.fp @@ -1,3 +1,4 @@ +//created by Evil Space Tomato uniform float timer; vec4 Process(vec4 color) From a92ce35d0d8a35c7fc283f56d261ced91d61bc85 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 29 Dec 2010 08:17:56 +0000 Subject: [PATCH 78/82] - removed some debug code. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1148 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/textures/gl_material.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 64bed441..becd0872 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -884,10 +884,6 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader) void FMaterial::BindPatch(int cm, int translation, int overrideshader) { - if (overrideshader > 0) - { - __asm nop - } int usebright = false; int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; From 43cb0dd6562338a2bdb0cdafeb4d6538422b375d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 31 Dec 2010 09:11:24 +0000 Subject: [PATCH 79/82] - implemented fuzz shaders for weapon HUD sprite. - added 2 more fuzz shaders. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1149 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/renderer/gl_renderer.h | 2 +- src/gl/scene/gl_sprite.cpp | 2 +- src/gl/scene/gl_weapon.cpp | 46 +++++++++++++++---- src/gl/shaders/gl_shader.cpp | 2 + wadsrc/static/menudef.z | 2 + wadsrc/static/shaders/glsl/fuzz_noise.fp | 22 +++++++++ .../static/shaders/glsl/fuzz_smoothnoise.fp | 20 ++++++++ 7 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 wadsrc/static/shaders/glsl/fuzz_noise.fp create mode 100644 wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 594ddfc9..a282b54f 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -106,7 +106,7 @@ public: void DrawScene(bool toscreen = false); void DrawBlend(sector_t * viewsector); - void DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep); + void DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep, int OverrideShader); void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep); void DrawTargeterSprites(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 3b309caf..b7df98d9 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -69,7 +69,7 @@ CVAR(Int, gl_billboard_mode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, gl_enhanced_nv_stealth, 3, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CUSTOM_CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE) { - if (self < 0 || self > 5) self = 0; + if (self < 0 || self > 7) self = 0; } extern bool r_showviewer; diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 91b2957c..15f51158 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -57,6 +57,7 @@ EXTERN_CVAR (Bool, r_drawplayersprites) EXTERN_CVAR(Float, transsouls) EXTERN_CVAR (Bool, st_scale) +EXTERN_CVAR(Int, gl_fuzztype) //========================================================================== @@ -65,7 +66,7 @@ EXTERN_CVAR (Bool, st_scale) // //========================================================================== -void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep) +void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep, int OverrideShader) { float fU1,fV1; float fU2,fV2; @@ -91,7 +92,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed FMaterial * tex = FMaterial::ValidateTexture(lump, false); if (!tex) return; - tex->BindPatch(cm_index, 0); + tex->BindPatch(cm_index, 0, OverrideShader); int vw = viewwidth; int vh = viewheight; @@ -144,7 +145,10 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed fV2=tex->GetVB(); } - if (tex->tex->gl_info.mIsTransparent) gl_RenderState.EnableAlphaTest(false); + if (tex->GetTransparent() || OverrideShader != 0) + { + gl_RenderState.EnableAlphaTest(false); + } gl_RenderState.Apply(); gl.Begin(GL_TRIANGLE_STRIP); gl.TexCoord2f(fU1, fV1); gl.Vertex2f(x1,y1); @@ -152,7 +156,10 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed gl.TexCoord2f(fU2, fV1); gl.Vertex2f(x2,y1); gl.TexCoord2f(fU2, fV2); gl.Vertex2f(x2,y2); gl.End(); - if (tex->tex->gl_info.mIsTransparent) gl_RenderState.EnableAlphaTest(true); + if (tex->GetTransparent() || OverrideShader != 0) + { + gl_RenderState.EnableAlphaTest(true); + } } //========================================================================== @@ -264,10 +271,31 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) } // Set the render parameters - vis.RenderStyle.CheckFuzz(); + + int OverrideShader = 0; + float trans = 0.f; + if (vis.RenderStyle.BlendOp >= STYLEOP_Fuzz && vis.RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub) + { + vis.RenderStyle.CheckFuzz(); + if (vis.RenderStyle.BlendOp == STYLEOP_Fuzz) + { + if (gl.shadermodel >= 4 && gl_fuzztype != 0) + { + // Todo: implement shader selection here + vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent]; + OverrideShader = gl_fuzztype + 4; + trans = 0.99f; // trans may not be 1 here + } + else + { + vis.RenderStyle.BlendOp = STYLEOP_Shadow; + } + } + statebright[0] = statebright[1] = false; + } + gl_SetRenderStyle(vis.RenderStyle, false, false); - float trans; if (vis.RenderStyle.Flags & STYLEF_TransSoulsAlpha) { trans = transsouls; @@ -276,7 +304,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { trans = 1.f; } - else + else if (trans == 0.f) { trans = FIXED2FLOAT(vis.alpha); } @@ -313,7 +341,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // set the lighting parameters (only calls glColor and glAlphaFunc) gl_SetSpriteLighting(vis.RenderStyle, playermo, statebright[i]? 255 : lightlevel, 0, &cmc, 0xffffff, trans, statebright[i], true); - DrawPSprite (player,psp,psp->sx+ofsx, psp->sy+ofsy, cm.colormap, hudModelStep); + DrawPSprite (player,psp,psp->sx+ofsx, psp->sy+ofsy, cm.colormap, hudModelStep, OverrideShader); } } gl_RenderState.EnableBrightmap(false); @@ -344,5 +372,5 @@ void FGLRenderer::DrawTargeterSprites() // The Targeter's sprites are always drawn normally. for (i=ps_targetcenter, psp = &player->psprites[ps_targetcenter]; istate) DrawPSprite (player,psp,psp->sx, psp->sy, CM_DEFAULT, false); + if (psp->state) DrawPSprite (player,psp,psp->sx, psp->sy, CM_DEFAULT, false, 0); } \ No newline at end of file diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index e7ff00a8..c3fd8955 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -394,6 +394,8 @@ static const FDefaultShader defaultshaders[]= {"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp"}, {"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp"}, {"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp"}, + {"Noise Fuzz", "shaders/glsl/fuzz_noise.fp"}, + {"Smooth Noise Fuzz", "shaders/glsl/fuzz_smoothnoise.fp"}, {NULL,NULL} }; diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index 16f07d39..e495e5da 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -131,6 +131,8 @@ OptionValue "FuzzStyle" 2, "Smooth fuzz" 3, "Swirly fuzz" 4, "Translucent fuzz" + 6, "Noise" + 7, "Smooth Noise" //5, "Jagged fuzz" I can't see any difference between this and 4 so it's disabled for now. } diff --git a/wadsrc/static/shaders/glsl/fuzz_noise.fp b/wadsrc/static/shaders/glsl/fuzz_noise.fp new file mode 100644 index 00000000..3f452e72 --- /dev/null +++ b/wadsrc/static/shaders/glsl/fuzz_noise.fp @@ -0,0 +1,22 @@ +//created by Evil Space Tomato +uniform float timer; + +vec4 Process(vec4 color) +{ + vec2 texCoord = gl_TexCoord[0].st; + vec4 basicColor = getTexel(texCoord) * color; + + texCoord.x = int(texCoord.x * 128) / 128.0f; + texCoord.y = int(texCoord.y * 128) / 128.0f; + + float texX = sin(mod(texCoord.x * 100 + timer*5, 3.489)) + texCoord.x / 4; + float texY = cos(mod(texCoord.y * 100 + timer*5, 3.489)) + texCoord.y / 4; + float vX = (texX/texY)*21.0f; + float vY = (texY/texX)*13.0f; + + + float test = mod(timer*2.0f+(vX + vY), 0.5f); + basicColor.a = basicColor.a * test; + basicColor.rgb = vec3(0.0f,0.0f,0.0f); + return basicColor; +} diff --git a/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp b/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp new file mode 100644 index 00000000..fb4c1e69 --- /dev/null +++ b/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp @@ -0,0 +1,20 @@ +//created by Evil Space Tomato +uniform float timer; + +vec4 Process(vec4 color) +{ + vec2 texCoord = gl_TexCoord[0].st; + vec4 basicColor = getTexel(texCoord) * color; + + float texX = sin(mod(texCoord.x * 100 + timer*5, 3.489)) + texCoord.x / 4; + float texY = cos(mod(texCoord.y * 100 + timer*5, 3.489)) + texCoord.y / 4; + float vX = (texX/texY)*21.0f; + float vY = (texY/texX)*13.0f; + + + float test = mod(timer*2.0f+(vX + vY), 0.5f); + basicColor.a = basicColor.a * test; + + basicColor.rgb = vec3(0.0f,0.0f,0.0f); + return basicColor; +} From 9a58f7cde01f34ff2954d991b9d213f9ca754222 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 31 Dec 2010 10:12:04 +0000 Subject: [PATCH 80/82] - fixed: Ensure that any vertex position only belongs to one mapsection. Overlapping linedefs can produce nodes where non-connecting subsectors can be in the same place and these were not properly handled by the mapsection builder. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1150 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_setup.cpp | 89 ++++++++++++++++++++++++++++++++++++++++ src/r_defs.h | 5 +++ 2 files changed, 94 insertions(+) diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index 9331370b..f36c0c78 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -130,6 +130,94 @@ static void DoSetMapSection(subsector_t *sub, int num) } } +//========================================================================== +// +// Merge sections. This is needed in case the map contains errors +// like overlapping lines resulting in abnormal subsectors. +// +// This function ensures that any vertex position can only be in one section. +// +//========================================================================== + +struct cvertex_t +{ + fixed_t x, y; + + operator int () const { return x ^ y; } + bool operator!= (const cvertex_t &other) const { return x != other.x || y != other.y; } + cvertex_t& operator =(const vertex_t *v) { x = v->x; y = v->y; return *this; } +}; + +typedef TMap FSectionVertexMap; + +static int MergeMapSections(int num) +{ + FSectionVertexMap vmap; + FSectionVertexMap::Pair *pair; + TArray sectmap; + TArray sectvalid; + sectmap.Resize(num); + sectvalid.Resize(num); + for(int i=0;iSubsector()->mapsection; + for(int j=0;j<2;j++) + { + vt = j==0? seg->v1:seg->v2; + vmap[vt] = section; + } + } + + // second step: Check if any seg references more than one mapsection, either by subsector or by vertex + for(DWORD i=0;iSubsector()->mapsection; + for(int j=0;j<2;j++) + { + vt = j==0? seg->v1:seg->v2; + int vsection = vmap[vt]; + + if (vsection != section) + { + // These 2 sections should be merged + for(int k=0;kValue == vsection) pair->Value = section; + } + sectvalid[vsection-1] = false; + } + } + } + for(int i=0;i Date: Fri, 31 Dec 2010 10:53:52 +0000 Subject: [PATCH 81/82] - added a fixed version Gez's 3D floor patch for Archvile resurrection and Heretic's Skullrod rain. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1151 b0f79afe-0144-0410-b225-9a4edf0717df --- src/g_heretic/a_hereticweaps.cpp | 30 ++++++++++++++++++ src/p_3dfloors.cpp | 54 ++++++++++++++++++++++++++++++++ src/p_3dfloors.h | 1 + src/p_enemy.cpp | 19 +++++++++++ 4 files changed, 104 insertions(+) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 0a44cdbe..f6c9df7f 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -1045,6 +1045,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) x = self->x + ((pr_storm()&127) - 64) * FRACUNIT; y = self->y + ((pr_storm()&127) - 64) * FRACUNIT; mo = Spawn (x, y, ONCEILINGZ, ALLOW_REPLACE); +#ifdef _3DFLOORS + // We used bouncecount to store the 3D floor index in A_HideInCeiling + if (!mo) return; + fixed_t newz; + if (self->bouncecount >= 0 + && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size()) + newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(x, y);// - 40 * FRACUNIT; + else + newz = self->Sector->ceilingplane.ZatPoint(x, y); + int moceiling = P_Find3DFloor(NULL, x, y, newz, false, false, newz); + if (moceiling >= 0) + mo->z = newz - mo->height; +#endif mo->Translation = multiplayer ? TRANSLATION(TRANSLATION_PlayersExtra,self->special2) : 0; mo->target = self->target; @@ -1084,6 +1097,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_RainImpact) DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling) { +#ifdef _3DFLOORS + // We use bouncecount to store the 3D floor index + fixed_t foo; + for (unsigned int i=0; i< self->Sector->e->XFloor.ffloors.Size(); i++) + { + F3DFloor * rover = self->Sector->e->XFloor.ffloors[i]; + if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + + if ((foo = rover->bottom.plane->ZatPoint(self->x, self->y)) >= (self->z + self->height)) + { + self->z = foo + 4*FRACUNIT; + self->bouncecount = i; + return; + } + } + self->bouncecount = -1; +#endif self->z = self->ceilingz + 4*FRACUNIT; } diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 390fc23c..6ba516db 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -707,5 +707,59 @@ secplane_t P_FindFloorPlane(sector_t * sector, fixed_t x, fixed_t y, fixed_t z) return retplane; } +//========================================================================== +// +// Gives the index to an extra floor above or below the given location. +// -1 means normal floor or ceiling +// +//========================================================================== + +int P_Find3DFloor(sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool above, bool floor, fixed_t &cmpz) +{ + // If no sector given, find the one appropriate + if (sec == NULL) + sec = R_PointInSubsector(x, y)->sector; + + // Above normal ceiling + cmpz = sec->ceilingplane.ZatPoint(x, y); + if (z >= cmpz) + return -1; + + // Below normal floor + cmpz = sec->floorplane.ZatPoint(x, y); + if (z <= cmpz) + return -1; + + // Looking through planes from top to bottom + for (int i = 0; i < (signed)sec->e->XFloor.ffloors.Size(); ++i) + { + F3DFloor *rover = sec->e->XFloor.ffloors[i]; + + // We are only interested in solid 3D floors here + if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + + if (above) + { + // z is above that floor + if (floor && (z >= (cmpz = rover->top.plane->ZatPoint(x, y)))) + return i - 1; + // z is above that ceiling + if (z >= (cmpz = rover->bottom.plane->ZatPoint(x, y))) + return i - 1; + } + else // below + { + // z is below that ceiling + if (!floor && (z <= (cmpz = rover->bottom.plane->ZatPoint(x, y)))) + return i; + // z is below that floor + if (z <= (cmpz = rover->top.plane->ZatPoint(x, y))) + return i; + } + } + + // Failsafe + return -1; +} #endif \ No newline at end of file diff --git a/src/p_3dfloors.h b/src/p_3dfloors.h index 6a0005ba..e58d316e 100644 --- a/src/p_3dfloors.h +++ b/src/p_3dfloors.h @@ -128,6 +128,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li fixed_t x, fixed_t y, fixed_t refx, fixed_t refy); secplane_t P_FindFloorPlane(sector_t * sector, fixed_t x, fixed_t y, fixed_t z); +int P_Find3DFloor(sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool above, bool floor, fixed_t &cmpz); #else diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 378aaae9..2a61f833 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2517,6 +2517,25 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) if ( abs(corpsehit-> x - viletryx) > maxdist || abs(corpsehit-> y - viletryy) > maxdist ) continue; // not actually touching +#ifdef _3DFLOORS + // Let's check if there are floors in between the archvile and its target + sector_t *vilesec = self->Sector; + sector_t *corpsec = corpsehit->Sector; + // We only need to test if at least one of the sectors has a 3D floor. + sector_t *testsec = vilesec->e->XFloor.ffloors.Size() ? vilesec : + (vilesec != corpsec && corpsec->e->XFloor.ffloors.Size()) ? corpsec : NULL; + if (testsec) + { + fixed_t zdist1, zdist2; + if (P_Find3DFloor(testsec, corpsehit->x, corpsehit->y, corpsehit->z, false, true, zdist1) + != P_Find3DFloor(testsec, self->x, self->y, self->z, false, true, zdist2)) + { + // Not on same floor + if (vilesec == corpsec || abs(zdist1 - self->z) > self->height) + continue; + } + } +#endif corpsehit->velx = corpsehit->vely = 0; // [RH] Check against real height and radius From 3cbdbdf01f1854658a622488594bce3d15dc92a3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 2 Jan 2011 15:49:41 +0000 Subject: [PATCH 82/82] - use a better hashkey for the vertex map used by the mapsection code. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1152 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/data/gl_setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index f36c0c78..55bbe0be 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -143,7 +143,7 @@ struct cvertex_t { fixed_t x, y; - operator int () const { return x ^ y; } + operator int () const { return ((x>>16)&0xffff) | y; } bool operator!= (const cvertex_t &other) const { return x != other.x || y != other.y; } cvertex_t& operator =(const vertex_t *v) { x = v->x; y = v->y; return *this; } };