Files
2026-01-06 11:37:29 +01:00

269 lines
8.6 KiB
HLSL

#include "ReShade.fxh"
texture FontTexture < source = "font.png"; >
{
Width = 512;
Height = 512;
Format = RGBA8;
};
sampler FontSampler { Texture = FontTexture; };
// Time dilation
uniform bool OSD_ShowTD = false;
uniform bool TD_Enabled = false;
uniform float TD_World = 1.0;
uniform float TD_AI = 1.0;
// God mode
uniform bool OSD_ShowGodMode = false;
uniform bool GodMode_Enabled = false;
// Ignore hits
uniform bool OSD_ShowIgnoreHits = false;
uniform bool IgnoreHits_Enabled = false;
// Stealth
uniform bool OSD_ShowStealth = false;
uniform bool Stealth_Enabled = false;
// --- Character arrays for labels ---
static const int ON_LENGTH = 2;
static float ON_CHARS[32] = {
79-32, 78-32, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
}; // "ON"
static const int OFF_LENGTH = 3;
static float OFF_CHARS[32] = {
79-32, 70-32, 70-32, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
}; // "OFF"
static const int TD_LABEL_LEN = 14;
static float TD_LABEL[32] = {
84-32, 105-32, 109-32, 101-32, 32-32, 100-32, 105-32, 108-32, // Time dilation :
97-32, 116-32, 105-32, 111-32, 110-32, 32-32,0,0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const int WORLD_LEN = 8;
static float WORLD_CHARS[32] = {
32-32, 87-32, 111-32, 114-32, 108-32, 100-32, 58-32, 32-32, // World :
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static const int AI_LEN = 5;
static float AI_CHARS[32] = {
32-32,65-32,73-32,58-32,32-32,0,0,0, // AI :
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
// New labels
static const int GOD_LEN = 9;
static float GOD_CHARS[32] = {
71-32, 111-32, 100-32, 32-32, 77-32, 111-32, 100-32, 101-32, // God Mode
32 -32, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static const int INV_LEN = 12;
static float INV_CHARS[32] = {
73-32, 103-32, 110-32, 111-32, 114-32, 101-32, 32-32, 104-32, // "Ignore hits"
105-32, 116-32, 115-32, 32-32, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static const int STEALTH_LEN = 13;
static float STEALTH_CHARS[32] = {
83-32, 116-32, 101-32, 97-32, 108-32, 116-32, 104-32, 32-32, // "Stealth Mode"
77-32, 111-32, 100-32, 101-32, 32-32, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
// --- SDF Rectangle ---
float sdRoundRect(float2 p, float2 b, float r) {
float2 q = abs(p) - b + r;
return min(max(q.x, q.y), 0.0) + length(max(q,0.0)) - r;
}
// --- Draw a character ---
float4 DrawChar(float2 uv, float2 pos, float2 charSize, float charIndex) {
float2 texSize = float2(14.0, 7.0);
float2 fontUV = float2(charIndex % texSize.x, floor(charIndex / texSize.x)) / texSize;
float2 fontUVSize = 1.0 / texSize;
float2 localUV = (uv - pos) / charSize;
float2 finalFontUV = fontUV + fontUVSize * localUV;
return tex2D(FontSampler, finalFontUV);
}
// --- Draw text array ---
float4 DrawText(float2 uv, float2 startPos, float2 charSize, float chars[32], int length) {
float4 col = float4(0,0,0,0);
[unroll]
for (int i = 0; i < 32; i++) {
if (i >= length) break;
float2 charPos = startPos + float2(i*charSize.x,0);
if (uv.x >= charPos.x && uv.x < charPos.x+charSize.x &&
uv.y >= charPos.y && uv.y < charPos.y+charSize.y) {
float4 glyph = DrawChar(uv,charPos,charSize,chars[i]);
col.rgb = lerp(col.rgb,glyph.rgb,glyph.a);
col.a = max(col.a,glyph.a);
}
}
return col;
}
// --- Draw float number as text ---
float4 DrawFloat(float2 uv, float2 startPos, float2 charSize, float value) {
float4 col = float4(0,0,0,0);
float v = abs(value);
int iv = (int)(v * 100.0 + 0.5);
int i0 = iv / 100;
int i1 = (iv / 10) % 10;
int i2 = iv % 10;
float chars[4];
chars[0] = i0 + 16; // '0'
chars[1] = 14; // '.'
chars[2] = i1 + 16;
chars[3] = i2 + 16;
//float chars[4] = { i0 + 16, 14, i1 + 16, i2 + 16 };
[unroll]
for (int i=0;i<4;i++) {
float2 pos = startPos + float2(i * charSize.x, 0);
if (uv.x >= pos.x && uv.x < pos.x+charSize.x &&
uv.y >= pos.y && uv.y < pos.y+charSize.y) {
float4 g = DrawChar(uv, pos, charSize, chars[i]);
col.rgb = lerp(col.rgb, g.rgb, g.a);
col.a = max(col.a, g.a);
}
}
return col;
}
// --- Alpha blend ---
void AlphaBlend(inout float4 dst, float4 src) {
dst.rgb = lerp(dst.rgb, src.rgb, src.a);
dst.a = max(dst.a, src.a);
}
// --- Draw ON/OFF flag dynamically ---
float4 DrawFlag(float2 uv, inout float2 pen, float2 charSize, const float label[32], int labelLen, bool enabled) {
float4 combined = DrawText(uv, pen, charSize, label, labelLen);
pen.x += labelLen*charSize.x;
float4 state = enabled ? DrawText(uv, pen, charSize, ON_CHARS, ON_LENGTH)
: DrawText(uv, pen, charSize, OFF_CHARS, OFF_LENGTH);
pen.x += (enabled ? ON_LENGTH : OFF_LENGTH)*charSize.x;
AlphaBlend(combined, state);
return combined;
}
// --- Pixel Shader ---
float4 PS_OSD(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target {
float4 col = tex2D(ReShade::BackBuffer, uv);
if (!OSD_ShowTD && !OSD_ShowGodMode && !OSD_ShowIgnoreHits && !OSD_ShowStealth)
return col;
float margin_top = 20.0;
float2 center_uv = float2(0.5, margin_top / ReShade::ScreenSize.y + 0.01);
float2 p = uv - center_uv; p.x *= ReShade::AspectRatio;
// --- Frame rect ---
float charAdvance = 0.003;
float2 charSize = float2(0.003, 0.02); // widht * height
float totalLen = 0;
float3 color;
if (TD_Enabled && OSD_ShowTD) {
totalLen = TD_LABEL_LEN + ON_LENGTH + WORLD_LEN + 4 + AI_LEN + 4;
color = float3(0.3, 1.0, 0.3); // Green
}
if (!TD_Enabled && OSD_ShowTD) {
totalLen = TD_LABEL_LEN + OFF_LENGTH;
color = float3(1.0, 0.3, 0.3); // Red
}
if (GodMode_Enabled && OSD_ShowGodMode) {
totalLen = GOD_LEN + ON_LENGTH;
color = float3(0.3, 1.0, 0.3);
}
if (!GodMode_Enabled && OSD_ShowGodMode) {
totalLen = GOD_LEN + OFF_LENGTH;
color = float3(1.0, 0.3, 0.3);
}
if (IgnoreHits_Enabled && OSD_ShowIgnoreHits) {
totalLen = INV_LEN + ON_LENGTH;
color = float3(0.3, 1.0, 0.3);
}
if (!IgnoreHits_Enabled && OSD_ShowIgnoreHits) {
totalLen = INV_LEN + OFF_LENGTH;
color = float3(1.0, 0.3, 0.3);
}
if (Stealth_Enabled && OSD_ShowStealth) {
totalLen = STEALTH_LEN + ON_LENGTH;
color = float3(0.3, 1.0, 0.3);
}
if (!Stealth_Enabled && OSD_ShowStealth) {
totalLen = STEALTH_LEN + OFF_LENGTH;
color = float3(1.0, 0.3, 0.3);
}
float2 size_uv = float2((totalLen* charAdvance * 0.5 + charAdvance * 1.0) * ReShade::AspectRatio, 20.0 / ReShade::ScreenSize.y);
float thickness_px = 1.0;
float thickness = thickness_px * ReShade::PixelSize.y;
float radius_px = 2.0;
float radius = radius_px * ReShade::PixelSize.y;
float d = sdRoundRect(p,size_uv,radius);
if (abs(d)<thickness) col.rgb = lerp(col.rgb, color, 0.85);
// --- Draw all flags ---
float2 pen = center_uv;
pen.x -= totalLen * charAdvance * 0.5;
pen.y -= charSize.y * 0.5;
float4 combined = float4(0,0,0,0);
// Time Dilation
if (OSD_ShowTD) {
AlphaBlend(combined, DrawText(uv, pen, charSize, TD_LABEL, TD_LABEL_LEN));
pen.x += TD_LABEL_LEN * charAdvance;
AlphaBlend(combined, TD_Enabled ? DrawText(uv, pen, charSize, ON_CHARS, ON_LENGTH)
: DrawText(uv, pen, charSize, OFF_CHARS, OFF_LENGTH));
pen.x += (TD_Enabled ? ON_LENGTH : OFF_LENGTH) * charAdvance;
if (TD_Enabled) {
AlphaBlend(combined, DrawText(uv, pen, charSize, WORLD_CHARS, WORLD_LEN));
pen.x += WORLD_LEN * charAdvance;
AlphaBlend(combined, DrawFloat(uv, pen, charSize, TD_World));
pen.x += 4 * charAdvance;
AlphaBlend(combined, DrawText(uv, pen, charSize, AI_CHARS, AI_LEN));
pen.x += AI_LEN * charAdvance;
AlphaBlend(combined, DrawFloat(uv, pen, charSize, TD_AI));
pen.x += 4 * charAdvance;
}
}
if (OSD_ShowGodMode)
AlphaBlend(combined, DrawFlag(uv, pen, charSize, GOD_CHARS, GOD_LEN, GodMode_Enabled));
if (OSD_ShowIgnoreHits)
AlphaBlend(combined, DrawFlag(uv, pen, charSize, INV_CHARS, INV_LEN, IgnoreHits_Enabled));
if (OSD_ShowStealth)
AlphaBlend(combined, DrawFlag(uv, pen, charSize, STEALTH_CHARS, STEALTH_LEN, Stealth_Enabled));
combined.rgb *= color;
col.rgb = lerp(col.rgb, combined.rgb, combined.a);
return col;
}
// --- Technique ---
technique OSD {
pass {
VertexShader = PostProcessVS;
PixelShader = PS_OSD;
}
}