From 73552f0365a70d46984e43f84d014fa755a59755 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Aug 2012 22:24:15 +0000 Subject: [PATCH] - Added HUD message visibility flags, which are ORed into the type field: * HUDMSG_NOTWITH3DVIEW : This message does not appear when the 3D view is active. * HUDMSG_NOTWITHFULLMAP : This message does not appear when the fullscreen automap is active. * HUDMSG_NOTWITHOVERLAYMAP : This message does not appear when the overlay automap is active. These flags may be combined, so for example: HUDMSG_NOTWITHFULLMAP | HUDMSG_NOTWITHOVERLAYMAP would prevent the message from appearing if any form of automap is active. - Added HUD message layers, which are ORed into the type field: * HUDMSG_LAYER_OVERHUD : This is the default and standard behavior. The message appear on top of most HUD elements. This definition is just included for completeness' sake; you don't need to explicitly use it. * HUDMSG_LAYER_UNDERHUD : The message appears underneath other HUD elements, such as the status bar. * HUDMSG_LAYER_OVERMAP : The message appears on top of the fullscreen automap. At the moment, this layer is functionally equivalent to using the flags HUDMSG_NOTWITH3DVIEW | HUDMSG_NOTWITHOVERLAYMAP. However, if Blzut3 decides to implement support for drawing the automap permanently on a second screen, messages on this layer will move to that screen with the automap and be permanently visible as long as the map is visible on that other screen. These are not flags, so for example HUDMSG_LAYER_UNDERHUD | HUDMSG_LAYER_OVERHUD is not valid. SVN r3821 (trunk) --- src/d_main.cpp | 8 +- src/g_shared/hudmessages.cpp | 17 ++- src/g_shared/sbar.h | 34 +++++- src/g_shared/shared_sbar.cpp | 229 ++++++++++++++++++++--------------- src/p_acs.cpp | 23 +++- 5 files changed, 199 insertions(+), 112 deletions(-) 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"