Skip to content

Commit e65d680

Browse files
committed
Gaming aspect bundle, tmux, ghostty
- Gaming aspect bundles all gaming stuff: steam, scopebuddy, mangohud, deadlock, wow into a single aspect. This single aspect is provided at host level - Gamemode added, and modified scopebuddy scripts to auto call it, niceness turned off - ghostty added - tmux added
1 parent b7c146c commit e65d680

18 files changed

Lines changed: 390 additions & 24 deletions

File tree

assets/ghostty/cursor_warp.glsl

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
//Taken from https://github.com/sahaj-b/ghostty-cursor-shaders
2+
// -- CONFIGURATION --
3+
vec4 TRAIL_COLOR = iCurrentCursorColor; // can change to eg: vec4(0.2, 0.6, 1.0, 0.5);
4+
const float DURATION = 0.08; // in seconds
5+
const float MAX_TRAIL_LENGTH = 0.15;
6+
const float THRESHOLD_MIN_DISTANCE = 1.0; // min distance to show trail (units of cursor width)
7+
const float BLUR = 2.0; // blur size in pixels (for antialiasing)
8+
9+
// --- CONSTANTS for easing functions ---
10+
const float PI = 3.14159265359;
11+
const float C1_BACK = 1.70158;
12+
const float C2_BACK = C1_BACK * 1.525;
13+
const float C3_BACK = C1_BACK + 1.0;
14+
const float C4_ELASTIC = (2.0 * PI) / 3.0;
15+
const float C5_ELASTIC = (2.0 * PI) / 4.5;
16+
const float SPRING_STIFFNESS = 9.0;
17+
const float SPRING_DAMPING = 0.9;
18+
19+
// --- EASING FUNCTIONS ---
20+
21+
// // Linear
22+
// float ease(float x) {
23+
// return x;
24+
// }
25+
26+
// // EaseOutQuad
27+
// float ease(float x) {
28+
// return 1.0 - (1.0 - x) * (1.0 - x);
29+
// }
30+
31+
// // EaseOutCubic
32+
// float ease(float x) {
33+
// return 1.0 - pow(1.0 - x, 3.0);
34+
// }
35+
36+
37+
// // EaseOutQuart
38+
// float ease(float x) {
39+
// return 1.0 - pow(1.0 - x, 4.0);
40+
// }
41+
42+
// // EaseOutQuint
43+
// float ease(float x) {
44+
// return 1.0 - pow(1.0 - x, 5.0);
45+
// }
46+
47+
// // EaseOutSine
48+
// float ease(float x) {
49+
// return sin((x * PI) / 2.0);
50+
// }
51+
52+
// // EaseOutExpo
53+
// float ease(float x) {
54+
// return x == 1.0 ? 1.0 : 1.0 - pow(2.0, -10.0 * x);
55+
// }
56+
57+
// EaseOutCirc
58+
float ease(float x) {
59+
return sqrt(1.0 - pow(x - 1.0, 2.0));
60+
}
61+
62+
// // EaseOutBack
63+
// float ease(float x) {
64+
// return 1.0 + C3_BACK * pow(x - 1.0, 3.0) + C1_BACK * pow(x - 1.0, 2.0);
65+
// }
66+
67+
// // EaseOutElastic
68+
// float ease(float x) {
69+
// return x == 0.0 ? 0.0
70+
// : x == 1.0 ? 1.0
71+
// : pow(2.0, -10.0 * x) * sin((x * 10.0 - 0.75) * C4_ELASTIC) + 1.0;
72+
// }
73+
74+
// Parametric Spring
75+
// float ease(float x) {
76+
// x = clamp(x, 0.0, 1.0);
77+
// float decay = exp(-SPRING_DAMPING * SPRING_STIFFNESS * x);
78+
// float freq = sqrt(SPRING_STIFFNESS * (1.0 - SPRING_DAMPING * SPRING_DAMPING));
79+
// float osc = cos(freq * 6.283185 * x) + (SPRING_DAMPING * sqrt(SPRING_STIFFNESS) / freq) * sin(freq * 6.283185 * x);
80+
// return 1.0 - decay * osc;
81+
// }
82+
83+
float getSdfRectangle(in vec2 p, in vec2 xy, in vec2 b)
84+
{
85+
vec2 d = abs(p - xy) - b;
86+
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
87+
}
88+
89+
// Based on Inigo Quilez's 2D distance functions article: https://iquilezles.org/articles/distfunctions2d/
90+
// Potencially optimized by eliminating conditionals and loops to enhance performance and reduce branching
91+
92+
float seg(in vec2 p, in vec2 a, in vec2 b, inout float s, float d) {
93+
vec2 e = b - a;
94+
vec2 w = p - a;
95+
vec2 proj = a + e * clamp(dot(w, e) / dot(e, e), 0.0, 1.0);
96+
float segd = dot(p - proj, p - proj);
97+
d = min(d, segd);
98+
99+
float c0 = step(0.0, p.y - a.y);
100+
float c1 = 1.0 - step(0.0, p.y - b.y);
101+
float c2 = 1.0 - step(0.0, e.x * w.y - e.y * w.x);
102+
float allCond = c0 * c1 * c2;
103+
float noneCond = (1.0 - c0) * (1.0 - c1) * (1.0 - c2);
104+
float flip = mix(1.0, -1.0, step(0.5, allCond + noneCond));
105+
s *= flip;
106+
return d;
107+
}
108+
109+
float getSdfParallelogram(in vec2 p, in vec2 v0, in vec2 v1, in vec2 v2, in vec2 v3) {
110+
float s = 1.0;
111+
float d = dot(p - v0, p - v0);
112+
113+
d = seg(p, v0, v3, s, d);
114+
d = seg(p, v1, v0, s, d);
115+
d = seg(p, v2, v1, s, d);
116+
d = seg(p, v3, v2, s, d);
117+
118+
return s * sqrt(d);
119+
}
120+
121+
vec2 normalize(vec2 value, float isPosition) {
122+
return (value * 2.0 - (iResolution.xy * isPosition)) / iResolution.y;
123+
}
124+
125+
float antialising(float distance) {
126+
return 1. - smoothstep(0., normalize(vec2(BLUR, BLUR), 0.).x, distance);
127+
}
128+
129+
float determineIfTopRightIsLeading(vec2 a, vec2 b) {
130+
float condition1 = step(b.x, a.x) * step(a.y, b.y); // a.x < b.x && a.y > b.y
131+
float condition2 = step(a.x, b.x) * step(b.y, a.y); // a.x > b.x && a.y < b.y
132+
133+
// if neither condition is met, return 1 (else case)
134+
return 1.0 - max(condition1, condition2);
135+
}
136+
137+
vec2 getRectangleCenter(vec4 rectangle) {
138+
return vec2(rectangle.x + (rectangle.z / 2.), rectangle.y - (rectangle.w / 2.));
139+
}
140+
141+
142+
void mainImage(out vec4 fragColor, in vec2 fragCoord){
143+
#if !defined(WEB)
144+
fragColor = texture(iChannel0, fragCoord.xy / iResolution.xy);
145+
#endif
146+
147+
// normalization & setup(-1, 1 coords)
148+
vec2 vu = normalize(fragCoord, 1.);
149+
vec2 offsetFactor = vec2(-.5, 0.5);
150+
151+
vec4 currentCursor = vec4(normalize(iCurrentCursor.xy, 1.), normalize(iCurrentCursor.zw, 0.));
152+
vec4 previousCursor = vec4(normalize(iPreviousCursor.xy, 1.), normalize(iPreviousCursor.zw, 0.));
153+
154+
vec2 centerCC = currentCursor.xy - (currentCursor.zw * offsetFactor);
155+
vec2 centerCP = previousCursor.xy - (previousCursor.zw * offsetFactor);
156+
157+
vec2 delta = centerCP - centerCC;
158+
float lineLength = length(delta);
159+
160+
float sdfCurrentCursor = getSdfRectangle(vu, centerCC, currentCursor.zw * 0.5);
161+
162+
vec4 newColor = vec4(fragColor);
163+
164+
float minDist = currentCursor.w * THRESHOLD_MIN_DISTANCE;
165+
float progress = clamp((iTime - iTimeCursorChange) / DURATION, 0.0, 1.0);
166+
if (lineLength > minDist) {
167+
// ANIMATION logic
168+
169+
float head_eased = 0.0;
170+
float tail_eased = 0.0;
171+
172+
float tail_delay_factor = MAX_TRAIL_LENGTH / lineLength;
173+
174+
float isLongMove = step(MAX_TRAIL_LENGTH, lineLength);
175+
176+
float head_eased_short = ease(progress);
177+
float tail_eased_short = ease(smoothstep(tail_delay_factor, 1.0, progress));
178+
float head_eased_long = 1.0;
179+
float tail_eased_long = ease(progress);
180+
181+
head_eased = mix(head_eased_long, head_eased_short, isLongMove);
182+
tail_eased = mix(tail_eased_long, tail_eased_short, isLongMove);
183+
184+
// detect straight moves
185+
vec2 delta_abs = abs(centerCC - centerCP);
186+
float threshold = 0.001;
187+
float isHorizontal = step(delta_abs.y, threshold);
188+
float isVertical = step(delta_abs.x, threshold);
189+
float isStraightMove = max(isHorizontal, isVertical);
190+
191+
// -- Making the parallelogram sdf (diagonal move) --
192+
193+
// animate the TOP-LEFT corners
194+
vec2 head_pos_tl = mix(previousCursor.xy, currentCursor.xy, head_eased);
195+
vec2 tail_pos_tl = mix(previousCursor.xy, currentCursor.xy, tail_eased);
196+
197+
float isTopRightLeading = determineIfTopRightIsLeading(currentCursor.xy, previousCursor.xy);
198+
float isBottomLeftLeading = 1.0 - isTopRightLeading;
199+
200+
// v0, v1 : "front" of the trail (head)
201+
vec2 v0 = vec2(head_pos_tl.x + currentCursor.z * isTopRightLeading, head_pos_tl.y - currentCursor.w);
202+
vec2 v1 = vec2(head_pos_tl.x + currentCursor.z * isBottomLeftLeading, head_pos_tl.y);
203+
204+
// v2, v3: "back" of the trail (tail)
205+
vec2 v2 = vec2(tail_pos_tl.x + currentCursor.z * isBottomLeftLeading, tail_pos_tl.y);
206+
vec2 v3 = vec2(tail_pos_tl.x + currentCursor.z * isTopRightLeading, tail_pos_tl.y - previousCursor.w);
207+
208+
float sdfTrail_diag = getSdfParallelogram(vu, v0, v1, v2, v3);
209+
210+
// -- Making the rectangle sdf (straight move) --
211+
212+
vec2 head_center = mix(centerCP, centerCC, head_eased);
213+
vec2 tail_center = mix(centerCP, centerCC, tail_eased);
214+
215+
vec2 min_center = min(head_center, tail_center);
216+
vec2 max_center = max(head_center, tail_center);
217+
218+
vec2 box_size = (max_center - min_center) + currentCursor.zw;
219+
vec2 box_center = (min_center + max_center) * 0.5;
220+
221+
float sdfTrail_rect = getSdfRectangle(vu, box_center, box_size * 0.5);
222+
223+
// -- FINAL SELECTING AND DRAWING --
224+
float sdfTrail = mix(sdfTrail_diag, sdfTrail_rect, isStraightMove);
225+
226+
vec4 trail = TRAIL_COLOR;
227+
float trailAlpha = antialising(sdfTrail);
228+
newColor = mix(newColor, trail, trailAlpha);
229+
230+
// punch hole
231+
newColor = mix(newColor, fragColor, step(sdfCurrentCursor, 0.));
232+
}
233+
234+
fragColor = newColor;
235+
}

assets/scopebuddy/AppID/570.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
SCB_NOSCOPE=1
22
SDL_AUDIODRIVER=pipewire
3-
command="mangohud $command -novid -prewarm -map dota -sdlaudiodriver pipewire"
3+
command="gamemoderun mangohud $command -novid -prewarm -map dota -sdlaudiodriver pipewire"

assets/scopebuddy/AppID/ascension.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
SCB_NOSCOPE=1
55
STEAM_COMPAT_DATA_PATH="/games/SteamLibrary/steamapps/compatdata/ascension"
66
TZ=EST5EDT
7-
command="$command"
7+
command="gamemoderun $command"

assets/scopebuddy/AppID/bnet.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ STEAM_COMPAT_DATA_PATH="/games/SteamLibrary/steamapps/compatdata/battlenet"
1010
DXVK_HDR=1
1111
PROTON_ENABLE_HDR=1
1212
TZ=EST5EDT
13-
command="$command"
13+
command="gamemoderun $command"

assets/scopebuddy/AppID/hots.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
# SCB_NOSCOPE=1
33
WINE_SIMULATE_WRITECOPY=1
44
STEAM_COMPAT_DATA_PATH="/games/SteamLibrary/steamapps/compatdata/battlenet"
5-
command="$command"
5+
command="gamemoderun $command"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SCB_APPID="soulframe" scb -- %command%
22
SCB_NOSCOPE=1
33
STEAM_COMPAT_DATA_PATH="/games/SteamLibrary/steamapps/compatdata/soulframe"
4-
command="$command"
4+
command="gamemoderun $command"
55

assets/scopebuddy/noscope.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ PROTON_XESS_UPGRADE=1
4949
# use this to see what command is run with scopebuddy
5050
# SCB_DEBUG=1
5151

52-
command="$command"
52+
command="gamemoderun $command"

assets/scopebuddy/scb.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ SCB_GAMESCOPE_ARGS="-w 3440 -h 1440 -W 3440 -H 1440 -r 143.92 --force-grab-curso
5454

5555
####
5656
# The finale
57-
command="$command"
57+
command="gamemoderun $command"

modules/den.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
den._.primary-user
4848
# Sets shell for user at OS and HM level
4949
(den._.user-shell "zsh")
50+
# Projects host aspect homeManager config to users
51+
den._.host-aspects
5052
# Provides per system inputs'
5153
# i.e environment.systemPackages = [ inputs'.nixpkgs.legacyPackages.hello ]
5254
den._.inputs'

modules/gaming/gaming.nix

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{ den, ... }:
2+
{
3+
den.aspects.gaming =
4+
{ user, ... }:
5+
{
6+
includes = [
7+
den.aspects.steam
8+
den.aspects.mangohud
9+
den.aspects.deadlock
10+
den.aspects.wow
11+
den.aspects.scopebuddy
12+
];
13+
14+
nixos =
15+
{ ... }:
16+
{
17+
programs.gamemode = {
18+
enable = true;
19+
# nice setting off
20+
enableRenice = false;
21+
};
22+
23+
users.users.${user.userName}.extraGroups = [ "gamemode" ];
24+
};
25+
};
26+
}

0 commit comments

Comments
 (0)