- split out the generic parts of the crosshair drawer.

This commit is contained in:
Christoph Oelckers 2020-10-27 22:42:35 +01:00
parent 44793e1509
commit fd6b7f9274
6 changed files with 229 additions and 119 deletions

View file

@ -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

View file

@ -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 <assert.h>
#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);
}

View file

@ -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)
};

View file

@ -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);

View file

@ -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);
}
//---------------------------------------------------------------------------

View file

@ -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
{