diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f020b5008d..6505299898 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -905,6 +905,7 @@ set (PCH_SOURCES g_statusbar/sbarinfo.cpp g_statusbar/sbar_mugshot.cpp g_statusbar/shared_sbar.cpp + g_statusbar/base_sbar.cpp rendering/2d/f_wipe.cpp rendering/2d/v_blend.cpp rendering/hwrenderer/hw_entrypoint.cpp diff --git a/src/g_statusbar/base_sbar.cpp b/src/g_statusbar/base_sbar.cpp new file mode 100644 index 0000000000..0e50fc806d --- /dev/null +++ b/src/g_statusbar/base_sbar.cpp @@ -0,0 +1,198 @@ +/* +** base_sbar.cpp +** Base status bar implementation +** +**--------------------------------------------------------------------------- +** Copyright 1998-2016 Randy Heit +** Copyright 2017-2020 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include + +#include "templates.h" +#include "base_sbar.h" +#include "printf.h" +#include "v_draw.h" +#include "cmdlib.h" +#include "texturemanager.h" +#include "c_cvars.h" + +FGameTexture* CrosshairImage; +static int CrosshairNum; + + +IMPLEMENT_CLASS(DStatusBarCore, false, false) + + +CVAR(Color, crosshaircolor, 0xff0000, CVAR_ARCHIVE); +CVAR(Int, crosshairhealth, 1, CVAR_ARCHIVE); +CVAR(Float, crosshairscale, 1.0, CVAR_ARCHIVE); +CVAR(Bool, crosshairgrow, false, CVAR_ARCHIVE); + + + +void ST_LoadCrosshair(int num, bool alwaysload) +{ + char name[16]; + char size; + + if (!alwaysload && CrosshairNum == num && CrosshairImage != NULL) + { // No change. + return; + } + + if (num == 0) + { + CrosshairNum = 0; + CrosshairImage = NULL; + return; + } + if (num < 0) + { + num = -num; + } + size = (twod->GetWidth() < 640) ? 'S' : 'B'; + + mysnprintf(name, countof(name), "XHAIR%c%d", size, num); + FTextureID texid = TexMan.CheckForTexture(name, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ShortNameOnly); + if (!texid.isValid()) + { + mysnprintf(name, countof(name), "XHAIR%c1", size); + texid = TexMan.CheckForTexture(name, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ShortNameOnly); + if (!texid.isValid()) + { + texid = TexMan.CheckForTexture("XHAIRS1", ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ShortNameOnly); + } + } + CrosshairNum = num; + CrosshairImage = TexMan.GetGameTexture(texid); +} + +void ST_UnloadCrosshair() +{ + CrosshairImage = NULL; + CrosshairNum = 0; +} + + +//--------------------------------------------------------------------------- +// +// DrawCrosshair +// +//--------------------------------------------------------------------------- + +void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale) +{ + uint32_t color; + double size; + int w, h; + + // Don't draw the crosshair if there is none + if (CrosshairImage == NULL) + { + return; + } + + if (crosshairscale > 0.0f) + { + size = twod->GetHeight() * crosshairscale * 0.005; + } + else + { + size = 1.; + } + + if (crosshairgrow) + { + size *= scale; + } + + w = int(CrosshairImage->GetDisplayWidth() * size); + h = int(CrosshairImage->GetDisplayHeight() * size); + + if (crosshairhealth == 1) + { + // "Standard" crosshair health (green-red) + int health = phealth; + + if (health >= 85) + { + color = 0x00ff00; + } + else + { + int red, green; + health -= 25; + if (health < 0) + { + health = 0; + } + if (health < 30) + { + red = 255; + green = health * 255 / 30; + } + else + { + red = (60 - health) * 255 / 30; + green = 255; + } + color = (red << 16) | (green << 8); + } + } + else if (crosshairhealth == 2) + { + // "Enhanced" crosshair health (blue-green-yellow-red) + int health = clamp(phealth, 0, 200); + float rr, gg, bb; + + float saturation = health < 150 ? 1.f : 1.f - (health - 150) / 100.f; + + HSVtoRGB(&rr, &gg, &bb, health * 1.2f, saturation, 1); + int red = int(rr * 255); + int green = int(gg * 255); + int blue = int(bb * 255); + + color = (red << 16) | (green << 8) | blue; + } + else + { + color = crosshaircolor; + } + + DrawTexture(twod, CrosshairImage, + xpos, ypos, + DTA_DestWidth, w, + DTA_DestHeight, h, + DTA_AlphaChannel, true, + DTA_FillColor, color & 0xFFFFFF, + TAG_DONE); +} + + diff --git a/src/g_statusbar/base_sbar.h b/src/g_statusbar/base_sbar.h new file mode 100644 index 0000000000..db0de04e7f --- /dev/null +++ b/src/g_statusbar/base_sbar.h @@ -0,0 +1,16 @@ +#pragma once + +#include "dobject.h" +class FGameTexture; +extern FGameTexture* CrosshairImage; +void ST_LoadCrosshair(int num, bool alwaysload); +void ST_UnloadCrosshair(); +void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale); + + + +class DStatusBarCore : public DObject +{ + DECLARE_CLASS(DStatusBarCore, DObject) + +}; \ No newline at end of file diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index b9b501846b..d15411b9c2 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -35,7 +35,7 @@ #ifndef __SBAR_H__ #define __SBAR_H__ -#include "dobject.h" +#include "base_sbar.h" #include "v_collection.h" #include "v_text.h" #include "renderstyle.h" @@ -356,10 +356,10 @@ public: }; -class DBaseStatusBar : public DObject +class DBaseStatusBar : public DStatusBarCore { friend class DSBarInfo; - DECLARE_CLASS (DBaseStatusBar, DObject) + DECLARE_CLASS (DBaseStatusBar, DStatusBarCore) HAS_OBJECT_POINTERS public: // Popup screens for Strife's status bar @@ -536,7 +536,6 @@ DBaseStatusBar *CreateCustomStatusBar(int script=0); void ST_LoadCrosshair(bool alwaysload=false); void ST_Clear(); void ST_CreateStatusBar(bool bTitleLevel); -extern FGameTexture *CrosshairImage; int GetInventoryIcon(AActor *item, uint32_t flags, int *applyscale = nullptr); diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 25260ea334..2593eaf249 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -63,6 +63,7 @@ #include "texturemanager.h" #include "v_palette.h" #include "v_draw.h" +#include "m_fixed.h" #include "../version.h" @@ -97,9 +98,6 @@ DBaseStatusBar *StatusBar; extern int setblocks; -FGameTexture *CrosshairImage; -static int CrosshairNum; - CVAR (Int, paletteflash, 0, CVAR_ARCHIVE) CVAR (Flag, pf_hexenweaps, paletteflash, PF_HEXENWEAPONS) CVAR (Flag, pf_poison, paletteflash, PF_POISON) @@ -132,10 +130,6 @@ CUSTOM_CVAR(Bool, hud_aspectscale, false, CVAR_ARCHIVE) CVAR (Bool, crosshairon, true, CVAR_ARCHIVE); CVAR (Int, crosshair, 0, CVAR_ARCHIVE) CVAR (Bool, crosshairforce, false, CVAR_ARCHIVE) -CVAR (Color, crosshaircolor, 0xff0000, CVAR_ARCHIVE); -CVAR (Int, crosshairhealth, 1, CVAR_ARCHIVE); -CVAR (Float, crosshairscale, 1.0, CVAR_ARCHIVE); -CVAR (Bool, crosshairgrow, false, CVAR_ARCHIVE); CUSTOM_CVAR(Int, am_showmaplabel, 2, CVAR_ARCHIVE) { if (self < 0 || self > 2) self = 2; @@ -233,7 +227,6 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawFrame) void ST_LoadCrosshair(bool alwaysload) { int num = 0; - char name[16], size; if (!crosshairforce && players[consoleplayer].camera != NULL && @@ -246,38 +239,10 @@ void ST_LoadCrosshair(bool alwaysload) { num = crosshair; } - if (!alwaysload && CrosshairNum == num && CrosshairImage != NULL) - { // No change. - return; - } - - if (num == 0) - { - CrosshairNum = 0; - CrosshairImage = NULL; - return; - } - if (num < 0) - { - num = -num; - } - size = (twod->GetWidth() < 640) ? 'S' : 'B'; - - mysnprintf (name, countof(name), "XHAIR%c%d", size, num); - FTextureID texid = TexMan.CheckForTexture(name, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ShortNameOnly); - if (!texid.isValid()) - { - mysnprintf (name, countof(name), "XHAIR%c1", size); - texid = TexMan.CheckForTexture(name, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ShortNameOnly); - if (!texid.isValid()) - { - texid = TexMan.CheckForTexture("XHAIRS1", ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ShortNameOnly); - } - } - CrosshairNum = num; - CrosshairImage = TexMan.GetGameTexture(texid); + ST_LoadCrosshair(num, alwaysload); } + //--------------------------------------------------------------------------- // // ST_Clear @@ -291,8 +256,7 @@ void ST_Clear() StatusBar->Destroy(); StatusBar = NULL; } - CrosshairImage = NULL; - CrosshairNum = 0; + ST_UnloadCrosshair(); } //--------------------------------------------------------------------------- @@ -1146,84 +1110,13 @@ void DBaseStatusBar::DrawCrosshair () ST_LoadCrosshair(); // Don't draw the crosshair if there is none - if (CrosshairImage == NULL || gamestate == GS_TITLELEVEL || r_viewpoint.camera->health <= 0) + if (gamestate == GS_TITLELEVEL || r_viewpoint.camera->health <= 0) { return; } + int health = Scale(CPlayer->health, 100, CPlayer->mo->GetDefault()->health); - if (crosshairscale > 0.0f) - { - size = twod->GetHeight() * crosshairscale / 200.; - } - else - { - size = 1.; - } - - if (crosshairgrow) - { - size *= CrosshairSize; - } - w = int(CrosshairImage->GetDisplayWidth() * size); - h = int(CrosshairImage->GetDisplayHeight() * size); - - if (crosshairhealth == 1) { - // "Standard" crosshair health (green-red) - int health = Scale(CPlayer->health, 100, CPlayer->mo->GetDefault()->health); - - if (health >= 85) - { - color = 0x00ff00; - } - else - { - int red, green; - health -= 25; - if (health < 0) - { - health = 0; - } - if (health < 30) - { - red = 255; - green = health * 255 / 30; - } - else - { - red = (60 - health) * 255 / 30; - green = 255; - } - color = (red<<16) | (green<<8); - } - } - else if (crosshairhealth == 2) - { - // "Enhanced" crosshair health (blue-green-yellow-red) - int health = clamp(Scale(CPlayer->health, 100, CPlayer->mo->GetDefault()->health), 0, 200); - float rr, gg, bb; - - float saturation = health < 150 ? 1.f : 1.f - (health - 150) / 100.f; - - HSVtoRGB(&rr, &gg, &bb, health * 1.2f, saturation, 1); - int red = int(rr * 255); - int green = int(gg * 255); - int blue = int(bb * 255); - - color = (red<<16) | (green<<8) | blue; - } - else - { - color = crosshaircolor; - } - - DrawTexture(twod, CrosshairImage, - viewwidth / 2 + viewwindowx, - viewheight / 2 + viewwindowy, - DTA_DestWidth, w, - DTA_DestHeight, h, - DTA_AlphaChannel, true, - DTA_FillColor, color & 0xFFFFFF, - TAG_DONE); + ST_DrawCrosshair(health, viewwidth / 2 + viewwindowx, viewheight / 2 + viewwindowy, CrosshairSize); } //--------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/ui/statusbar/statusbar.zs b/wadsrc/static/zscript/ui/statusbar/statusbar.zs index 4f6e204a22..7164e7628f 100644 --- a/wadsrc/static/zscript/ui/statusbar/statusbar.zs +++ b/wadsrc/static/zscript/ui/statusbar/statusbar.zs @@ -1,3 +1,6 @@ +class StatusBarCore native +{ +} struct MugShot { @@ -108,7 +111,7 @@ class HUDMessageBase native ui virtual native void Draw(int bottom, int visibility); } -class BaseStatusBar native ui +class BaseStatusBar : StatusBarCore native ui { enum EPop {