diff --git a/src/d_main.cpp b/src/d_main.cpp index a9e02edff..40c724496 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -804,17 +804,21 @@ void D_Display () if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10) { + StatusBar->DrawBottomStuff (HUD_None); if (DrawFSHUD || automapactive) DrawHUD(); StatusBar->DrawTopStuff (HUD_None); } else if (viewheight == SCREENHEIGHT && viewactive && screenblocks > 10) { - StatusBar->Draw (DrawFSHUD ? HUD_Fullscreen : HUD_None); - StatusBar->DrawTopStuff (DrawFSHUD ? HUD_Fullscreen : HUD_None); + EHudState state = DrawFSHUD ? HUD_Fullscreen : HUD_None; + StatusBar->DrawBottomStuff (state); + StatusBar->Draw (state); + StatusBar->DrawTopStuff (state); } else { + StatusBar->DrawBottomStuff (HUD_StatusBar); StatusBar->Draw (HUD_StatusBar); StatusBar->DrawTopStuff (HUD_StatusBar); } diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index 22e12ead1..7216f6f30 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -140,6 +140,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h State = 0; SourceText = copystring (text); Font = font; + VisibilityFlags = 0; ResetText (SourceText); } @@ -184,6 +185,14 @@ void DHUDMessage::Serialize (FArchive &arc) Lines = NULL; ResetText (SourceText); } + if (SaveVersion < 3821) + { + VisibilityFlags = 0; + } + else + { + arc << VisibilityFlags; + } } //============================================================================ @@ -262,7 +271,7 @@ bool DHUDMessage::Tick () // //============================================================================ -void DHUDMessage::Draw (int bottom) +void DHUDMessage::Draw (int bottom, int visibility) { int xscale, yscale; int x, y; @@ -271,6 +280,12 @@ void DHUDMessage::Draw (int bottom) bool clean = false; int hudheight; + // If any of the visibility flags match, do NOT draw this message. + if (VisibilityFlags & visibility) + { + return; + } + DrawSetup (); int screen_width = SCREENWIDTH; diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 22a99709d..893287022 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -66,13 +66,18 @@ public: virtual void Serialize (FArchive &arc); - void Draw (int bottom); + void Draw (int bottom, int visibility); virtual void ResetText (const char *text); virtual void DrawSetup (); virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight); virtual bool Tick (); // Returns true to indicate time for removal virtual void ScreenSizeChanged (); + void SetVisibility(int vis) + { + VisibilityFlags = vis; + } + protected: FBrokenLines *Lines; int Width, Height, NumLines; @@ -81,6 +86,7 @@ protected: int HoldTics; int Tics; int State; + int VisibilityFlags; int HUDWidth, HUDHeight; EColorRange TextColor; FFont *Font; @@ -95,6 +101,14 @@ private: friend class DBaseStatusBar; }; +// HUD message visibility flags +enum +{ + HUDMSG_NotWith3DView = 1, + HUDMSG_NotWithFullMap = 2, + HUDMSG_NotWithOverlayMap = 4, +}; + // HUD Message; appear instantly, then fade out type ------------------------ class DHUDMessageFadeOut : public DHUDMessage @@ -242,6 +256,16 @@ int FindMugShotStateIndex(FName state); class FTexture; class AAmmo; +enum +{ + HUDMSGLayer_OverHUD, + HUDMSGLayer_UnderHUD, + HUDMSGLayer_OverMap, + + NUM_HUDMSGLAYERS, + HUDMSGLayer_Default = HUDMSGLayer_OverHUD, +}; + class DBaseStatusBar : public DObject { DECLARE_CLASS (DBaseStatusBar, DObject) @@ -281,11 +305,10 @@ public: void SetScaled (bool scale, bool force=false); - void AttachMessage (DHUDMessage *msg, uint32 id=0); + void AttachMessage (DHUDMessage *msg, uint32 id=0, int layer=HUDMSGLayer_Default); DHUDMessage *DetachMessage (DHUDMessage *msg); DHUDMessage *DetachMessage (uint32 id); void DetachAllMessages (); - bool CheckMessage (DHUDMessage *msg); void ShowPlayerName (); fixed_t GetDisplacement () { return Displacement; } int GetPlayer (); @@ -296,6 +319,7 @@ public: virtual void Tick (); virtual void Draw (EHudState state); + void DrawBottomStuff (EHudState state); void DrawTopStuff (EHudState state); virtual void FlashItem (const PClass *itemtype); virtual void AttachToPlayer (player_t *player); @@ -364,10 +388,10 @@ public: private: DBaseStatusBar() {} bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const; - void DrawMessages (int bottom); + void DrawMessages (int layer, int bottom); void DrawConsistancy () const; - TObjPtr Messages; + TObjPtr Messages[NUM_HUDMSGLAYERS]; bool ShowLog; }; diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 28741ed47..7f55fe0d0 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -220,7 +220,7 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres) FixedOrigin = false; CrosshairSize = FRACUNIT; RelTop = reltop; - Messages = NULL; + memset(Messages, 0, sizeof(Messages)); Displacement = 0; CPlayer = NULL; ShowLog = false; @@ -238,16 +238,17 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres) void DBaseStatusBar::Destroy () { - DHUDMessage *msg; - - msg = Messages; - while (msg) + for (int i = 0; i < countof(Messages); ++i) { - DHUDMessage *next = msg->Next; - msg->Destroy(); - msg = next; + DHUDMessage *msg = Messages[i]; + while (msg) + { + DHUDMessage *next = msg->Next; + msg->Destroy(); + msg = next; + } + Messages[i] = NULL; } - Messages = NULL; Super::Destroy(); } @@ -339,32 +340,35 @@ void DBaseStatusBar::MultiplayerChanged () void DBaseStatusBar::Tick () { - DHUDMessage *msg = Messages; - DHUDMessage **prev = &Messages; - - while (msg) + for (int i = 0; i < countof(Messages); ++i) { - DHUDMessage *next = msg->Next; + DHUDMessage *msg = Messages[i]; + DHUDMessage **prev = &Messages[i]; - if (msg->Tick ()) + while (msg) { - *prev = next; - msg->Destroy(); - } - else - { - prev = &msg->Next; - } - msg = next; - } + DHUDMessage *next = msg->Next; - // If the crosshair has been enlarged, shrink it. - if (CrosshairSize > FRACUNIT) - { - CrosshairSize -= XHAIRSHRINKSIZE; - if (CrosshairSize < FRACUNIT) + if (msg->Tick ()) + { + *prev = next; + msg->Destroy(); + } + else + { + prev = &msg->Next; + } + msg = next; + } + + // If the crosshair has been enlarged, shrink it. + if (CrosshairSize > FRACUNIT) { - CrosshairSize = FRACUNIT; + CrosshairSize -= XHAIRSHRINKSIZE; + if (CrosshairSize < FRACUNIT) + { + CrosshairSize = FRACUNIT; + } } } } @@ -375,7 +379,7 @@ void DBaseStatusBar::Tick () // //--------------------------------------------------------------------------- -void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id) +void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id, int layer) { DHUDMessage *old = NULL; DHUDMessage **prev; @@ -387,7 +391,7 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id) old->Destroy(); } - prev = &Messages; + prev = &Messages[layer]; // The ID serves as a priority, where lower numbers appear in front of // higher numbers. (i.e. The list is sorted in descending order, since @@ -412,48 +416,56 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id) DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg) { - DHUDMessage *probe = Messages; - DHUDMessage **prev = &Messages; + for (int i = 0; i < countof(Messages); ++i) + { + DHUDMessage *probe = Messages[i]; + DHUDMessage **prev = &Messages[i]; - while (probe && probe != msg) - { - prev = &probe->Next; - probe = probe->Next; - } - if (probe != NULL) - { - *prev = probe->Next; - probe->Next = NULL; - // Redraw the status bar in case it was covered - if (screen != NULL) + while (probe && probe != msg) { - SB_state = screen->GetPageCount(); + prev = &probe->Next; + probe = probe->Next; + } + if (probe != NULL) + { + *prev = probe->Next; + probe->Next = NULL; + // Redraw the status bar in case it was covered + if (screen != NULL) + { + SB_state = screen->GetPageCount(); + } + return probe; } } - return probe; + return NULL; } DHUDMessage *DBaseStatusBar::DetachMessage (DWORD id) { - DHUDMessage *probe = Messages; - DHUDMessage **prev = &Messages; + for (int i = 0; i < countof(Messages); ++i) + { + DHUDMessage *probe = Messages[i]; + DHUDMessage **prev = &Messages[i]; - while (probe && probe->SBarID != id) - { - prev = &probe->Next; - probe = probe->Next; - } - if (probe != NULL) - { - *prev = probe->Next; - probe->Next = NULL; - // Redraw the status bar in case it was covered - if (screen != NULL) + while (probe && probe->SBarID != id) { - SB_state = screen->GetPageCount(); + prev = &probe->Next; + probe = probe->Next; + } + if (probe != NULL) + { + *prev = probe->Next; + probe->Next = NULL; + // Redraw the status bar in case it was covered + if (screen != NULL) + { + SB_state = screen->GetPageCount(); + } + return probe; } } - return probe; + return NULL; } //--------------------------------------------------------------------------- @@ -464,31 +476,18 @@ DHUDMessage *DBaseStatusBar::DetachMessage (DWORD id) void DBaseStatusBar::DetachAllMessages () { - DHUDMessage *probe = Messages; - - Messages = NULL; - while (probe != NULL) + for (int i = 0; i < countof(Messages); ++i) { - DHUDMessage *next = probe->Next; - probe->Destroy(); - probe = next; - } -} + DHUDMessage *probe = Messages[i]; -//--------------------------------------------------------------------------- -// -// PROC CheckMessage -// -//--------------------------------------------------------------------------- - -bool DBaseStatusBar::CheckMessage (DHUDMessage *msg) -{ - DHUDMessage *probe = Messages; - while (probe && probe != msg) - { - probe = probe->Next; + Messages[i] = NULL; + while (probe != NULL) + { + DHUDMessage *next = probe->Next; + probe->Destroy(); + probe = next; + } } - return (probe == msg); } //--------------------------------------------------------------------------- @@ -1191,13 +1190,23 @@ void DBaseStatusBar::FlashCrosshair () // //--------------------------------------------------------------------------- -void DBaseStatusBar::DrawMessages (int bottom) +void DBaseStatusBar::DrawMessages (int layer, int bottom) { - DHUDMessage *msg = Messages; + DHUDMessage *msg = Messages[layer]; + int visibility = 0; + + if (viewactive) + { + visibility |= HUDMSG_NotWith3DView; + } + if (automapactive) + { + visibility |= viewactive ? HUDMSG_NotWithOverlayMap : HUDMSG_NotWithFullMap; + } while (msg) { DHUDMessage *next = msg->Next; - msg->Draw (bottom); + msg->Draw (bottom, visibility); msg = next; } } @@ -1445,6 +1454,17 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b { } +//--------------------------------------------------------------------------- +// +// DrawBottomStuff +// +//--------------------------------------------------------------------------- + +void DBaseStatusBar::DrawBottomStuff (EHudState state) +{ + DrawMessages (HUDMSGLayer_UnderHUD, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT); +} + //--------------------------------------------------------------------------- // // DrawTopStuff @@ -1462,16 +1482,11 @@ void DBaseStatusBar::DrawTopStuff (EHudState state) } DrawPowerups (); - - if (state == HUD_StatusBar) + if (automapactive && !viewactive) { - DrawMessages (::ST_Y); + DrawMessages (HUDMSGLayer_OverMap, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT); } - else - { - DrawMessages (SCREENHEIGHT); - } - + DrawMessages (HUDMSGLayer_OverHUD, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT); DrawConsistancy (); if (ShowLog && MustDrawLog(state)) DrawLog (); @@ -1597,7 +1612,18 @@ void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon) void DBaseStatusBar::Serialize (FArchive &arc) { - arc << Messages; + if (SaveVersion < 3821) + { + memset(Messages, 0, sizeof(Messages)); + arc << Messages[HUDMSGLayer_Default]; + } + else + { + for (int i = 0; i < countof(Messages); ++i) + { + arc << Messages[i]; + } + } } void DBaseStatusBar::ScreenSizeChanged () @@ -1605,11 +1631,14 @@ void DBaseStatusBar::ScreenSizeChanged () st_scale.Callback (); SB_state = screen->GetPageCount (); - DHUDMessage *message = Messages; - while (message != NULL) + for (int i = 0; i < countof(Messages); ++i) { - message->ScreenSizeChanged (); - message = message->Next; + DHUDMessage *message = Messages[i]; + while (message != NULL) + { + message->ScreenSizeChanged (); + message = message->Next; + } } } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fe2001411..36c086179 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -86,10 +86,23 @@ FRandom pr_acs ("ACS"); #define STACK_SIZE 4096 #define CLAMPCOLOR(c) (EColorRange)((unsigned)(c) >= NUM_TEXT_COLORS ? CR_UNTRANSLATED : (c)) -#define HUDMSG_LOG (0x80000000) -#define HUDMSG_COLORSTRING (0x40000000) #define LANGREGIONMASK MAKE_ID(0,0,0xff,0xff) +// HUD message flags +#define HUDMSG_LOG (0x80000000) +#define HUDMSG_COLORSTRING (0x40000000) +#define HUDMSG_ADDBLEND (0x20000000) + +// HUD message layers; these are not flags +#define HUDMSG_LAYER_SHIFT 12 +#define HUDMSG_LAYER_MASK (0x0000F000) +// See HUDMSGLayer enumerations in sbar.h + +// HUD message visibility flags +#define HUDMSG_VISIBILITY_SHIFT 16 +#define HUDMSG_VISIBILITY_MASK (0x00070000) +// See HUDMSG visibility enumerations in sbar.h + // Flags for ReplaceTextures #define NOT_BOTTOM 1 #define NOT_MIDDLE 2 @@ -5681,7 +5694,7 @@ scriptwait: color = CLAMPCOLOR(Stack[optstart-4]); } - switch (type & 0xFFFF) + switch (type & 0xFF) { default: // normal msg = new DHUDMessage (activefont, work, x, y, hudwidth, hudheight, color, holdTime); @@ -5707,7 +5720,9 @@ scriptwait: } break; } - StatusBar->AttachMessage (msg, id ? 0xff000000|id : 0); + msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT); + StatusBar->AttachMessage (msg, id ? 0xff000000|id : 0, + (type & HUDMSG_LAYER_MASK) >> HUDMSG_LAYER_SHIFT); if (type & HUDMSG_LOG) { static const char bar[] = TEXTCOLOR_ORANGE "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"