1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/*
* Copyright © 2025 Michael Smith <mikesmiffy128@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "con_.h"
#include "engineapi.h"
#include "feature.h"
#include "gamedata.h"
#include "hexcolour.h"
#include "hud.h"
#include "intdefs.h"
#include "vcall.h"
FEATURE("custom crosshair drawing")
REQUIRE(hud)
DECL_VFUNC_DYN(bool, IsInGame)
DEF_FEAT_CVAR(sst_xhair, "Enable custom crosshair", 0, CON_ARCHIVE)
DEF_FEAT_CVAR(sst_xhair_colour,
"Colour for custom crosshair (RGBA hex)", "FFFFFF", CON_ARCHIVE)
DEF_FEAT_CVAR_MIN(sst_xhair_thickness,
"Thickness of custom crosshair in pixels", 2, 1, CON_ARCHIVE)
DEF_FEAT_CVAR_MIN(sst_xhair_size,
"Length of lines in custom crosshair in pixels", 8, 0, CON_ARCHIVE)
DEF_FEAT_CVAR_MIN(sst_xhair_gap,
"Gap between lines in custom crosshair in pixels", 16, 0, CON_ARCHIVE)
DEF_FEAT_CVAR(sst_xhair_dot,
"Whether to draw dot in middle of custom crosshair", 1, CON_ARCHIVE)
DEF_FEAT_CVAR(sst_xhair_outline,
"Whether to draw outline around custom crosshair", 0, CON_ARCHIVE)
static struct rgba colour = {255, 255, 255, 255};
static void colourcb(struct con_var *v) {
hexcolour_rgba(colour.bytes, con_getvarstr(v));
}
static inline void drawrect(int x0, int y0, int x1, int y1, struct rgba colour,
bool outline) {
hud_drawrect(x0, y0, x1, y1, colour, true);
if (outline) hud_drawrect(x0, y0, x1, y1, (struct rgba){.a = 255}, false);
}
HANDLE_EVENT(HudPaint, int w, int h) {
if (!con_getvari(sst_xhair)) return;
if (has_vtidx_IsInGame && engclient && !IsInGame(engclient)) return;
int thick = con_getvari(sst_xhair_thickness);
int thick1 = (thick + 1) / 2, thick2 = thick - thick1;
int sz = con_getvari(sst_xhair_size);
int gap = con_getvari(sst_xhair_gap);
int gap1 = (gap + 1) / 2, gap2 = gap - gap1;
int x = w / 2, y = h / 2;
bool ol = !!con_getvari(sst_xhair_outline);
if (sz) {
drawrect(x - thick1, y - sz - gap1, x + thick2, y - gap1, colour, ol);
drawrect(x - thick1, y + gap2, x + thick2, y + sz + gap2, colour, ol);
drawrect(x - sz - gap1, y - thick1, x - gap1, y + thick2, colour, ol);
drawrect(x + gap2, y - thick1, x + sz + gap2, y + thick2, colour, ol);
}
if (con_getvari(sst_xhair_dot) && (gap >= thick || ol)) {
drawrect(x - thick1, y - thick1, x + thick2, y + thick2, colour, ol);
}
}
INIT {
sst_xhair_colour->cb = &colourcb;
return FEAT_OK;
}
// vi: sw=4 ts=4 noet tw=80 cc=80
|