mirror of
https://github.com/ENSL/NS.git
synced 2024-11-22 12:41:33 +00:00
WIP crosshair system
This commit is contained in:
parent
b3fcf00ea8
commit
f0f16adfe6
8 changed files with 364 additions and 1 deletions
|
@ -4,6 +4,7 @@
|
|||
#include "chudmisc.h"
|
||||
#include "hud_spectator.h"
|
||||
#include "AvHFont.h"
|
||||
#include "hud_crosshairs.h"
|
||||
|
||||
|
||||
class CHud
|
||||
|
@ -82,7 +83,8 @@ public:
|
|||
CHudAmmoSecondary m_AmmoSecondary;
|
||||
CHudTextMessage m_TextMessage;
|
||||
CHudStatusIcons m_StatusIcons;
|
||||
|
||||
CHudCrosshairs m_Crosshairs;
|
||||
|
||||
AvHFont mFont;
|
||||
AvHFont mSmallFont;
|
||||
|
||||
|
|
|
@ -164,6 +164,8 @@
|
|||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Playtest|Win32'">MaxSpeed</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Playtest|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hudgl.cpp" />
|
||||
<ClCompile Include="hud_crosshairs.cpp" />
|
||||
<ClCompile Include="hud_msg.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Playtest|Win32'">MaxSpeed</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Playtest|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
@ -799,6 +801,8 @@
|
|||
<ClInclude Include="GameStudioModelRenderer.h" />
|
||||
<ClInclude Include="health.h" />
|
||||
<ClInclude Include="hud.h" />
|
||||
<ClInclude Include="hudgl.h" />
|
||||
<ClInclude Include="hud_crosshairs.h" />
|
||||
<ClInclude Include="hud_iface.h" />
|
||||
<ClInclude Include="hud_servers.h" />
|
||||
<ClInclude Include="hud_servers_priv.h" />
|
||||
|
|
|
@ -594,6 +594,12 @@
|
|||
<ClCompile Include="cdll_int.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hud_crosshairs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hudgl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\mod\AvHAlienAbilities.h">
|
||||
|
@ -1040,6 +1046,12 @@
|
|||
<ClInclude Include="..\textrep\TRTagValuePair.h">
|
||||
<Filter>textrep</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hud_crosshairs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hudgl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="..\lib\public\game_controls.lib" />
|
||||
|
|
|
@ -251,6 +251,7 @@ void CHud :: Init( void )
|
|||
m_AmmoSecondary.Init();
|
||||
m_TextMessage.Init();
|
||||
m_StatusIcons.Init();
|
||||
m_Crosshairs.Init();
|
||||
|
||||
m_Spectator.m_chatEnabled = (m_SayText.m_HUD_saytext->value!=0);
|
||||
|
||||
|
@ -414,6 +415,7 @@ void CHud :: VidInit( void )
|
|||
m_AmmoSecondary.VidInit();
|
||||
m_TextMessage.VidInit();
|
||||
m_StatusIcons.VidInit();
|
||||
m_Crosshairs.VidInit();
|
||||
GetClientVoiceMgr()->VidInit();
|
||||
}
|
||||
|
||||
|
|
208
main/source/cl_dll/hud_crosshairs.cpp
Normal file
208
main/source/cl_dll/hud_crosshairs.cpp
Normal file
|
@ -0,0 +1,208 @@
|
|||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
#include "hudgl.h"
|
||||
|
||||
int CHudCrosshairs::Init()
|
||||
{
|
||||
m_iFlags = HUD_ACTIVE;
|
||||
|
||||
cl_cross = CVAR_CREATE("cl_cross", "0", FCVAR_ARCHIVE);
|
||||
cl_cross_color = CVAR_CREATE("cl_cross_color", "0 255 0", FCVAR_ARCHIVE);
|
||||
cl_cross_alpha = CVAR_CREATE("cl_cross_alpha", "255", FCVAR_ARCHIVE);
|
||||
cl_cross_thickness = CVAR_CREATE("cl_cross_thickness", "2", FCVAR_ARCHIVE);
|
||||
cl_cross_size = CVAR_CREATE("cl_cross_size", "10", FCVAR_ARCHIVE);
|
||||
cl_cross_gap = CVAR_CREATE("cl_cross_gap", "3", FCVAR_ARCHIVE);
|
||||
cl_cross_outline = CVAR_CREATE("cl_cross_outline", "0", FCVAR_ARCHIVE);
|
||||
//cl_cross_outline_alpha = CVAR_CREATE("cl_cross_outline_alpha", "255", FCVAR_ARCHIVE);
|
||||
cl_cross_outline_inner = CVAR_CREATE("cl_cross_outline_inner", "1", FCVAR_ARCHIVE);
|
||||
//cl_cross_circle_radius = CVAR_CREATE("cl_cross_circle_radius", "0", FCVAR_ARCHIVE);
|
||||
cl_cross_dot_size = CVAR_CREATE("cl_cross_dot_size", "0", FCVAR_ARCHIVE);
|
||||
cl_cross_dot_color = CVAR_CREATE("cl_cross_dot_color", "", FCVAR_ARCHIVE);
|
||||
cl_cross_dot_outline = CVAR_CREATE("cl_cross_dot_outline", "1", FCVAR_ARCHIVE);
|
||||
cl_cross_top_line = CVAR_CREATE("cl_cross_top_line", "1", FCVAR_ARCHIVE);
|
||||
cl_cross_bottom_line = CVAR_CREATE("cl_cross_bottom_line", "1", FCVAR_ARCHIVE);
|
||||
cl_cross_left_line = CVAR_CREATE("cl_cross_left_line", "1", FCVAR_ARCHIVE);
|
||||
cl_cross_right_line = CVAR_CREATE("cl_cross_right_line", "1", FCVAR_ARCHIVE);
|
||||
|
||||
gHUD.AddHudElem(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CHudCrosshairs::VidInit()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHudCrosshairs::Draw(float time)
|
||||
{
|
||||
if (cl_cross->value == 0.0f)
|
||||
return 0;
|
||||
|
||||
unsigned char alpha;
|
||||
if (sscanf(cl_cross_alpha->string, "%hhu", &alpha) != 1)
|
||||
alpha = 255;
|
||||
|
||||
if (alpha == 0)
|
||||
return 0;
|
||||
|
||||
//// outline alpha perhaps unnecessary since odd numbered thicknesses feather the outline edges
|
||||
//unsigned char outalpha;
|
||||
//if (sscanf(cl_cross_outline_alpha->string, "%hhu", &outalpha) != 1)
|
||||
// outalpha = 255;
|
||||
//
|
||||
//if (outalpha == 0)
|
||||
// return 0;
|
||||
|
||||
unsigned char r, g, b;
|
||||
if (sscanf(cl_cross_color->string, "%hhu %hhu %hhu", &r, &g, &b) != 3) {
|
||||
r = 0;
|
||||
g = 255;
|
||||
b = 0;
|
||||
}
|
||||
|
||||
|
||||
Vector2D center(ScreenWidth() / 2.0f, ScreenHeight() / 2.0f);
|
||||
|
||||
HudGL gl;
|
||||
|
||||
// Draw the outline.
|
||||
// TODO: this contains a terrible amount of repeating complex code.
|
||||
// Possible solution: can be changed to this with the one downside being in rare cases where cl_cross_thickness is high AND its alpha is <255, the center of each line will be slightly darker. ex. below is for bottom line. Would also cause certain crosshairs that have outlines on invisible cross lines to not look right.
|
||||
// gl.rectangle(Vector2D(center.x + offset, center.y + gap - half_width), Vector2D(center.x - offset, center.y + gap + size + half_width));
|
||||
if (cl_cross_outline->value > 0.0f) {
|
||||
gl.color(0, 0, 0, alpha);
|
||||
//gl.color(0, 0, 0, outalpha);
|
||||
gl.line_width(cl_cross_outline->value);
|
||||
|
||||
auto size = cl_cross_size->value;
|
||||
auto gap = cl_cross_gap->value;
|
||||
auto half_thickness = cl_cross_thickness->value / 2.0f;
|
||||
auto half_width = cl_cross_outline->value / 2.0f;
|
||||
auto offset = half_thickness + half_width;
|
||||
|
||||
// Top line
|
||||
if (cl_cross_top_line->value) {
|
||||
gl.line(Vector2D(center.x - offset, center.y - gap - size), Vector2D(center.x + offset, center.y - gap - size));
|
||||
if (cl_cross_outline_inner->value == 0.0f)
|
||||
{
|
||||
gl.line(Vector2D(center.x + half_thickness, center.y - gap - size + half_width), Vector2D(center.x + half_thickness, center.y - gap));
|
||||
gl.line(Vector2D(center.x - half_thickness, center.y - gap), Vector2D(center.x - half_thickness, center.y - gap - size + half_width));
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.line(Vector2D(center.x + half_thickness, center.y - gap - size + half_width), Vector2D(center.x + half_thickness, center.y - gap - half_width));
|
||||
gl.line(Vector2D(center.x + offset, center.y - gap), Vector2D(center.x - offset, center.y - gap));
|
||||
gl.line(Vector2D(center.x - half_thickness, center.y - gap - half_width), Vector2D(center.x - half_thickness, center.y - gap - size + half_width));
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom line
|
||||
if (cl_cross_bottom_line->value) {
|
||||
gl.line(Vector2D(center.x - offset, center.y + gap + size), Vector2D(center.x + offset, center.y + gap + size));
|
||||
if (cl_cross_outline_inner->value == 0.0f)
|
||||
{
|
||||
gl.line(Vector2D(center.x + half_thickness, center.y + gap + size - half_width), Vector2D(center.x + half_thickness, center.y + gap));
|
||||
gl.line(Vector2D(center.x - half_thickness, center.y + gap), Vector2D(center.x - half_thickness, center.y + gap + size - half_width));
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.line(Vector2D(center.x + half_thickness, center.y + gap + size - half_width), Vector2D(center.x + half_thickness, center.y + gap + half_width));
|
||||
gl.line(Vector2D(center.x + offset, center.y + gap), Vector2D(center.x - offset, center.y + gap));
|
||||
gl.line(Vector2D(center.x - half_thickness, center.y + gap + half_width), Vector2D(center.x - half_thickness, center.y + gap + size - half_width));
|
||||
}
|
||||
}
|
||||
|
||||
// Left line
|
||||
if (cl_cross_left_line->value) {
|
||||
gl.line(Vector2D(center.x - gap - size, center.y - offset), Vector2D(center.x - gap - size, center.y + offset));
|
||||
if (cl_cross_outline_inner->value == 0.0f)
|
||||
{
|
||||
gl.line(Vector2D(center.x - gap - size + half_width, center.y + half_thickness), Vector2D(center.x - gap, center.y + half_thickness));
|
||||
gl.line(Vector2D(center.x - gap, center.y - half_thickness), Vector2D(center.x - gap - size + half_width, center.y - half_thickness));
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.line(Vector2D(center.x - gap - size + half_width, center.y + half_thickness), Vector2D(center.x - gap - half_width, center.y + half_thickness));
|
||||
gl.line(Vector2D(center.x - gap, center.y + offset), Vector2D(center.x - gap, center.y - offset));
|
||||
gl.line(Vector2D(center.x - gap - half_width, center.y - half_thickness), Vector2D(center.x - gap - size + half_width, center.y - half_thickness));
|
||||
}
|
||||
}
|
||||
|
||||
// Right line
|
||||
if (cl_cross_right_line->value) {
|
||||
gl.line(Vector2D(center.x + gap + size, center.y - offset), Vector2D(center.x + gap + size, center.y + offset));
|
||||
if (cl_cross_outline_inner->value == 0.0f)
|
||||
{
|
||||
gl.line(Vector2D(center.x + gap + size - half_width, center.y + half_thickness), Vector2D(center.x + gap, center.y + half_thickness));
|
||||
gl.line(Vector2D(center.x + gap, center.y - half_thickness), Vector2D(center.x + gap + size - half_width, center.y - half_thickness));
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.line(Vector2D(center.x + gap + size - half_width, center.y + half_thickness), Vector2D(center.x + gap + half_width, center.y + half_thickness));
|
||||
gl.line(Vector2D(center.x + gap, center.y + offset), Vector2D(center.x + gap, center.y - offset));
|
||||
gl.line(Vector2D(center.x + gap + half_width, center.y - half_thickness), Vector2D(center.x + gap + size - half_width, center.y - half_thickness));
|
||||
}
|
||||
}
|
||||
|
||||
// Dot
|
||||
if (cl_cross_dot_size->value > 0.0f && cl_cross_dot_outline->value > 0.0f) {
|
||||
auto size = cl_cross_dot_size->value;
|
||||
auto offset = Vector2D(size / 2.0f, size / 2.0f);
|
||||
auto dot_half_width = cl_cross_dot_outline->value / 2.0f;
|
||||
|
||||
gl.line(Vector2D(center.x - offset.x - dot_half_width, center.y - offset.y), Vector2D(center.x + offset.x + dot_half_width, center.y - offset.y));
|
||||
gl.line(Vector2D(center.x + offset.x, center.y - offset.y + dot_half_width), Vector2D(center.x + offset.x, center.y + offset.y - dot_half_width));
|
||||
gl.line(Vector2D(center.x - offset.x, center.y - offset.y + dot_half_width), Vector2D(center.x - offset.x, center.y + offset.y - dot_half_width));
|
||||
gl.line(Vector2D(center.x - offset.x - dot_half_width, center.y + offset.y), Vector2D(center.x + offset.x + dot_half_width, center.y + offset.y));
|
||||
}
|
||||
}
|
||||
|
||||
gl.color(r, g, b, alpha);
|
||||
|
||||
// Draw the crosshairs.
|
||||
if (cl_cross_thickness->value > 0.0f) {
|
||||
gl.line_width(cl_cross_thickness->value);
|
||||
|
||||
auto size = cl_cross_size->value;
|
||||
auto gap = cl_cross_gap->value;
|
||||
|
||||
if (cl_cross_top_line->value)
|
||||
gl.line(Vector2D(center.x, center.y - gap - size), Vector2D(center.x, center.y - gap));
|
||||
if (cl_cross_bottom_line->value)
|
||||
gl.line(Vector2D(center.x, center.y + gap + size), Vector2D(center.x, center.y + gap));
|
||||
if (cl_cross_left_line->value)
|
||||
gl.line(Vector2D(center.x - gap - size, center.y), Vector2D(center.x - gap, center.y));
|
||||
if (cl_cross_right_line->value)
|
||||
gl.line(Vector2D(center.x + gap + size, center.y), Vector2D(center.x + gap, center.y));
|
||||
}
|
||||
|
||||
// PLZ FIX: compile errors
|
||||
//// Draw the circle.
|
||||
//if (cl_cross_circle_radius->value > 0.0f) {
|
||||
// gl.line_width(1.0f);
|
||||
|
||||
// auto radius = cl_cross_circle_radius->value;
|
||||
// if (old_circle_radius != radius) {
|
||||
// // Recompute the circle points.
|
||||
// circle_points = HudGL::compute_circle(radius);
|
||||
// old_circle_radius = radius;
|
||||
// }
|
||||
|
||||
// gl.circle(center, circle_points);
|
||||
//}
|
||||
|
||||
// Draw the dot.
|
||||
if (cl_cross_dot_size->value > 0.0f) {
|
||||
unsigned char r, g, b;
|
||||
if (sscanf(cl_cross_dot_color->string, "%hhu %hhu %hhu", &r, &g, &b) == 3)
|
||||
gl.color(r, g, b, alpha);
|
||||
|
||||
auto size = cl_cross_dot_size->value;
|
||||
auto offset = Vector2D(size / 2.0f, size / 2.0f);
|
||||
|
||||
gl.rectangle(center - offset, center + offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
30
main/source/cl_dll/hud_crosshairs.h
Normal file
30
main/source/cl_dll/hud_crosshairs.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
|
||||
class CHudCrosshairs : public CHudBase
|
||||
{
|
||||
cvar_t* cl_cross;
|
||||
cvar_t* cl_cross_color;
|
||||
cvar_t* cl_cross_alpha;
|
||||
cvar_t* cl_cross_thickness;
|
||||
cvar_t* cl_cross_size;
|
||||
cvar_t* cl_cross_gap;
|
||||
cvar_t* cl_cross_outline;
|
||||
cvar_t* cl_cross_outline_inner;
|
||||
//cvar_t* cl_cross_circle_radius;
|
||||
cvar_t* cl_cross_dot_size;
|
||||
cvar_t* cl_cross_dot_color;
|
||||
cvar_t* cl_cross_dot_outline;
|
||||
cvar_t* cl_cross_top_line;
|
||||
cvar_t* cl_cross_bottom_line;
|
||||
cvar_t* cl_cross_left_line;
|
||||
cvar_t* cl_cross_right_line;
|
||||
|
||||
//float old_circle_radius;
|
||||
//std::vector<Vector2D> circle_points;
|
||||
|
||||
public:
|
||||
virtual int Init();
|
||||
virtual int VidInit();
|
||||
virtual int Draw(float time);
|
||||
};
|
88
main/source/cl_dll/hudgl.cpp
Normal file
88
main/source/cl_dll/hudgl.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#define _USE_MATH_DEFINES
|
||||
#include "util_vector.h"
|
||||
#include "hudgl.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
HudGL::HudGL() {
|
||||
// Same steps as FillRGBA does.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
HudGL::~HudGL() {
|
||||
// Reset the line width in case we changed it.
|
||||
glLineWidth(1.0f);
|
||||
|
||||
// Same steps as FillRGBA does.
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void HudGL::color(float r, float g, float b, float a) const {
|
||||
glColor4f(r, g, b, a);
|
||||
}
|
||||
|
||||
void HudGL::color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const {
|
||||
glColor4ub(r, g, b, a);
|
||||
}
|
||||
|
||||
void HudGL::line_width(float width) const {
|
||||
glLineWidth(width);
|
||||
}
|
||||
|
||||
void HudGL::line(const Vector2D& start, const Vector2D& end) const {
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(start.x, start.y);
|
||||
glVertex2f(end.x, end.y);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
// to fix
|
||||
//void HudGL::circle(const Vector2D& center, const std::vector<Vector2D>& points) const {
|
||||
// glBegin(GL_LINE_STRIP);
|
||||
//
|
||||
// for (const auto& point ,: points)
|
||||
// glVertex2f(center.x + point.x, center.y + point.y);
|
||||
//
|
||||
// glVertex2f(center.x + points[0].x, center.y + points[0].y);
|
||||
// glEnd();
|
||||
//}
|
||||
|
||||
void HudGL::rectangle(const Vector2D& corner_a, const Vector2D& corner_b) const {
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(corner_a.x, corner_a.y);
|
||||
glVertex2f(corner_a.x, corner_b.y);
|
||||
glVertex2f(corner_b.x, corner_b.y);
|
||||
glVertex2f(corner_b.x, corner_a.y);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// to fix
|
||||
//std::vector<Vector2D> HudGL::compute_circle(float radius) {
|
||||
// // Maximum allowed distance between the circle and the rendered line segment.
|
||||
// const float MAX_ERROR = 0.1f;
|
||||
// const unsigned segment_count =
|
||||
// static_cast<unsigned>(std::ceil(M_PI / std::acos((radius - MAX_ERROR) / radius)));
|
||||
//
|
||||
// std::vector<Vector2D> points;
|
||||
// points.reserve(segment_count);
|
||||
//
|
||||
// for (unsigned i = 0; i < segment_count; ++i) {
|
||||
// float angle = static_cast<float>(M_PI * 2 * i / segment_count);
|
||||
// points.emplace_back(radius * std::cos(angle), radius * std::sin(angle));
|
||||
// }
|
||||
//
|
||||
// return points;
|
||||
//}
|
17
main/source/cl_dll/hudgl.h
Normal file
17
main/source/cl_dll/hudgl.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
# pragma comment(lib,"opengl32.lib")
|
||||
#include <vector>
|
||||
|
||||
class HudGL {
|
||||
public:
|
||||
HudGL();
|
||||
~HudGL();
|
||||
|
||||
void color(float r, float g, float b, float a) const;
|
||||
void color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const;
|
||||
void line_width(float width) const;
|
||||
void line(const Vector2D& start, const Vector2D& end) const;
|
||||
void circle(const Vector2D& center, const std::vector<Vector2D>& points) const;
|
||||
void rectangle(const Vector2D& corner_a, const Vector2D& corner_b) const;
|
||||
|
||||
static std::vector<Vector2D> compute_circle(float radius);
|
||||
};
|
Loading…
Reference in a new issue