diff --git a/addCRTModes.sh b/addCRTModes.sh index 04b4d13..2005dd1 100755 --- a/addCRTModes.sh +++ b/addCRTModes.sh @@ -10,7 +10,10 @@ addMode "1280x960_120i" 105.90 1280 1360 1496 1712 960 963 969 1031 -HSync +VSyn addMode "1600x900_120i" 120.000 1600 1696 1864 2128 900 903 908 975 -HSync +VSync Interlace addMode "1600x1000_120i" 133.000 1600 1696 1864 2128 1000 1003 1008 1075 -HSync +VSync Interlace #addMode "640x480_120p" 52.50 640 680 744 848 480 483 487 518 -hsync +vsync -addMode "640x480_120p" 52.41 640 680 744 848 480 481 484 515 +HSync -Vsync +#addMode "640x480_120p" 52.41 640 680 744 848 480 481 484 515 +HSync -Vsync +#addMode "640x480_120p" 52.35 640 680 744 848 480 481 484 515 +HSync -Vsync #flicker fix (119hz) +#addMode "640x480_120p" 51.97 640 680 744 848 480 481 484 515 +HSync -Vsync +addMode "640x480_120p" 52.95 640 680 748 856 480 482 485 516 -HSync +VSync addMode "480x360_120p" 29.00 480 504 552 624 360 363 367 389 -hsync +vsync #enter the gungeon addMode "760x284_120p" 35.50 760 792 864 968 284 287 297 308 -hsync +vsync #downwell addMode "1920x240_120p" 92.443 1920 2202 2266 2744 240 245 250 281 -HSync -VSync diff --git a/controller-off/compile.sh b/controller-off/compile.sh new file mode 100755 index 0000000..5b16a79 --- /dev/null +++ b/controller-off/compile.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cc controller-off.c -o controller-off $(pkg-config --cflags --libs sdl3) diff --git a/controller-off/controller-off b/controller-off/controller-off new file mode 100755 index 0000000..4a05ad9 Binary files /dev/null and b/controller-off/controller-off differ diff --git a/controller-off/controller-off.c b/controller-off/controller-off.c new file mode 100644 index 0000000..c4752c2 --- /dev/null +++ b/controller-off/controller-off.c @@ -0,0 +1,704 @@ +/* + * controller-off.c + * + * Global SDL3 controller disconnect utility. + * + * Button combination: + * + * Guide/Home + North + * + * SDL mapping: + * + * PlayStation -> Home + Triangle + * Xbox -> Guide + Y + * Nintendo -> Home + X + * + * Build: + * + * cc controller-off.c -o controller-off \ + * $(pkg-config --cflags --libs sdl3) + * + * Run: + * + * ./controller-off + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_CONTROLLERS 32 +#define MAC_LEN 18 + +typedef struct { + SDL_JoystickID id; + SDL_Gamepad *gamepad; + + int guide_pressed; + int north_pressed; + + /* + * Prevent repeated triggers while both buttons + * remain held. + */ + int triggered; +} Controller; + +static Controller controllers[MAX_CONTROLLERS]; +static int controller_count = 0; + +static volatile sig_atomic_t running = 1; + + +/* + * ------------------------------------------------------------ + * Check for XX:XX:XX:XX:XX:XX + * ------------------------------------------------------------ + */ +static int is_mac(const char *s) +{ + if (!s || strlen(s) != 17) + return 0; + + for (int i = 0; i < 17; i++) { + + if (i == 2 || + i == 5 || + i == 8 || + i == 11 || + i == 14) { + + if (s[i] != ':') + return 0; + + } else { + + if (!isxdigit( + (unsigned char)s[i])) + return 0; + } + } + + return 1; +} + + +/* + * ------------------------------------------------------------ + * Find a connected Bluetooth device whose name matches + * the SDL controller name. + * + * bluetoothctl output: + * + * Device AA:BB:CC:DD:EE:FF PS3 Controller + * + * We use: + * + * bluetoothctl devices Connected + * ------------------------------------------------------------ + */ +static int find_bluetooth_device( + const char *controller_name, + char mac[MAC_LEN]) +{ + if (!controller_name) + return 0; + + FILE *fp = popen( + "bluetoothctl devices Connected 2>/dev/null", + "r" + ); + + if (!fp) + return 0; + + char line[1024]; + + while (fgets( + line, + sizeof(line), + fp + )) { + + char candidate_mac[MAC_LEN]; + char device_name[768]; + + memset( + candidate_mac, + 0, + sizeof(candidate_mac) + ); + + memset( + device_name, + 0, + sizeof(device_name) + ); + + + /* + * bluetoothctl: + * + * Device MAC NAME + */ + if (sscanf( + line, + "Device %17s %[^\n]", + candidate_mac, + device_name + ) != 2) { + + continue; + } + + + if (!is_mac(candidate_mac)) + continue; + + + /* + * SDL and bluetoothctl may use slightly + * different names. + * + * First try exact match. + */ + if (strcmp( + controller_name, + device_name + ) == 0) { + + strncpy( + mac, + candidate_mac, + MAC_LEN + ); + + mac[MAC_LEN - 1] = '\0'; + + pclose(fp); + + return 1; + } + + + /* + * PS3-specific fallback. + * + * SDL: + * + * PS3 Controller + * + * BlueZ: + * + * PLAYSTATION(R)3 Controller + */ + if ( + strstr(controller_name, "PS3") && + strstr(device_name, "3 Controller") + ) { + + strncpy( + mac, + candidate_mac, + MAC_LEN + ); + + mac[MAC_LEN - 1] = '\0'; + + pclose(fp); + + return 1; + } + } + + pclose(fp); + + return 0; +} + + +/* + * ------------------------------------------------------------ + * Disconnect Bluetooth device. + * ------------------------------------------------------------ + */ +static void disconnect_bluetooth( + const char *mac) +{ + if (!is_mac(mac)) + return; + + + printf( + "Disconnecting Bluetooth device %s\n", + mac + ); + + fflush(stdout); + + + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return; + } + + + if (pid == 0) { + + /* + * Suppress bluetoothctl output. + */ + FILE *devnull = + fopen("/dev/null", "w"); + + if (devnull) { + + dup2( + fileno(devnull), + STDOUT_FILENO + ); + + dup2( + fileno(devnull), + STDERR_FILENO + ); + + fclose(devnull); + } + + + execlp( + "bluetoothctl", + "bluetoothctl", + "disconnect", + mac, + (char *)NULL + ); + + + _exit(127); + } + + + /* + * Reap child process. + */ + waitpid( + pid, + NULL, + 0 + ); +} + + +/* + * ------------------------------------------------------------ + * Handle the button combination. + * ------------------------------------------------------------ + */ +static void disconnect_controller( + Controller *controller) +{ + if (!controller || + !controller->gamepad) + return; + + + const char *name = + SDL_GetGamepadName( + controller->gamepad + ); + + + printf("\n"); + printf( + "PS/Home + North detected\n" + ); + + printf( + "Controller: %s\n", + name ? name : "Unknown" + ); + + + char mac[MAC_LEN]; + + + if (!find_bluetooth_device( + name, + mac + )) { + + fprintf( + stderr, + "Could not find a connected Bluetooth " + "device matching \"%s\".\n", + name ? name : "Unknown" + ); + + return; + } + + + printf( + "Bluetooth MAC: %s\n", + mac + ); + + + disconnect_bluetooth(mac); +} + + +/* + * ------------------------------------------------------------ + * Find SDL controller. + * ------------------------------------------------------------ + */ +static Controller *find_controller( + SDL_JoystickID id) +{ + for (int i = 0; + i < controller_count; + i++) { + + if (controllers[i].id == id) + return &controllers[i]; + } + + return NULL; +} + + +/* + * ------------------------------------------------------------ + * Add controller. + * ------------------------------------------------------------ + */ +static void add_controller( + SDL_JoystickID id) +{ + if (controller_count >= + MAX_CONTROLLERS) { + + fprintf( + stderr, + "Controller limit reached.\n" + ); + + return; + } + + + SDL_Gamepad *gamepad = + SDL_OpenGamepad(id); + + + if (!gamepad) { + + fprintf( + stderr, + "SDL_OpenGamepad failed: %s\n", + SDL_GetError() + ); + + return; + } + + + Controller *controller = + &controllers[ + controller_count++ + ]; + + + memset( + controller, + 0, + sizeof(*controller) + ); + + + controller->id = id; + controller->gamepad = gamepad; + + + const char *name = + SDL_GetGamepadName(gamepad); + + + printf( + "Controller connected: %s\n", + name ? name : "Unknown" + ); +} + + +/* + * ------------------------------------------------------------ + * Remove controller. + * ------------------------------------------------------------ + */ +static void remove_controller( + SDL_JoystickID id) +{ + for (int i = 0; + i < controller_count; + i++) { + + if (controllers[i].id != id) + continue; + + + SDL_CloseGamepad( + controllers[i].gamepad + ); + + + /* + * Fill the removed slot with the last + * controller. + */ + controllers[i] = + controllers[ + controller_count - 1 + ]; + + + controller_count--; + + return; + } +} + + +/* + * ------------------------------------------------------------ + * Signal handler. + * ------------------------------------------------------------ + */ +static void handle_signal( + int signal) +{ + (void)signal; + + running = 0; +} + + +/* + * ------------------------------------------------------------ + * Main + * ------------------------------------------------------------ + */ +int main(void) +{ + signal( + SIGINT, + handle_signal + ); + + signal( + SIGTERM, + handle_signal + ); + + + if (!SDL_Init( + SDL_INIT_GAMEPAD)) { + + fprintf( + stderr, + "SDL_Init failed: %s\n", + SDL_GetError() + ); + + return 1; + } + + + /* + * Receive controller events even though we have + * no window/focus. + */ + SDL_SetHint( + SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, + "1" + ); + + + printf( + "====================================\n" + " Controller Off\n" + "====================================\n" + "Hold Home/Guide + Triangle/North\n" + "to disconnect the controller.\n\n" + ); + + + /* + * Open controllers that already exist. + */ + int count = 0; + + SDL_JoystickID *ids = + SDL_GetGamepads(&count); + + + if (ids) { + + for (int i = 0; + i < count; + i++) { + + add_controller(ids[i]); + } + + SDL_free(ids); + } + + + SDL_Event event; + + + while (running) { + + while (SDL_PollEvent(&event)) { + + + /* + * Controller added. + */ + if (event.type == + SDL_EVENT_GAMEPAD_ADDED) { + + add_controller( + event.gdevice.which + ); + } + + + /* + * Controller removed. + */ + else if (event.type == + SDL_EVENT_GAMEPAD_REMOVED) { + + remove_controller( + event.gdevice.which + ); + } + + + /* + * Button press/release. + */ + else if ( + event.type == + SDL_EVENT_GAMEPAD_BUTTON_DOWN || + + event.type == + SDL_EVENT_GAMEPAD_BUTTON_UP + ) { + + Controller *controller = + find_controller( + event.gbutton.which + ); + + + if (!controller) + continue; + + + int pressed = + event.type == + SDL_EVENT_GAMEPAD_BUTTON_DOWN; + + + /* + * Guide/Home/PS. + */ + if (event.gbutton.button == + SDL_GAMEPAD_BUTTON_GUIDE) { + + controller->guide_pressed = + pressed; + } + + + /* + * North: + * + * PS = Triangle + * Xbox = Y + * Nintendo = X + */ + if (event.gbutton.button == + SDL_GAMEPAD_BUTTON_NORTH) { + + controller->north_pressed = + pressed; + } + + + /* + * Trigger only once per press. + */ + if (controller->guide_pressed && + controller->north_pressed && + !controller->triggered) { + + controller->triggered = 1; + + disconnect_controller( + controller + ); + } + + + /* + * Allow another trigger after + * either button is released. + */ + if (!controller->guide_pressed || + !controller->north_pressed) { + + controller->triggered = 0; + } + } + } + + + SDL_Delay(5); + } + + + /* + * Cleanup. + */ + for (int i = 0; + i < controller_count; + i++) { + + if (controllers[i].gamepad) + SDL_CloseGamepad( + controllers[i].gamepad + ); + } + + + SDL_Quit(); + + return 0; +} + diff --git a/profile b/profile new file mode 100644 index 0000000..c2d5eb1 --- /dev/null +++ b/profile @@ -0,0 +1,155 @@ +#profile: executed by the command interpreter for login shells. +# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login +# exists. +# see /usr/share/doc/bash/examples/startup-files for examples. +# the files are located in the bash-doc package. + +# the default umask is set in /etc/profile; for setting the umask +# for ssh logins, install and configure the libpam-umask package. +#umask 022 + + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" +fi + +#text colors +txtblk='\e[0;30m' # Black - Regular +txtred='\e[0;31m' # Red +txtgrn='\e[0;32m' # Green +txtylw='\e[0;33m' # Yellow +txtblu='\e[0;34m' # Blue +txtpur='\e[0;35m' # Purple +txtcyn='\e[0;36m' # Cyan +txtwht='\e[0;37m' # White + +x="/etc/X11/xorg.conf.d" +xmonad="$HOME/.xmonad/xmonad.hs" +xmo=$xmonad +gpc="$HOME/mnt/gaming-win/C:/Users/lucka/" +brc="$HOME/.bashrc" +alias v="vim" +alias s="sudo" +alias mg="sshfs gaming-pc.mario:/ ~/mnt/gaming-pc" +alias mt="sshfs lucka@terraria.mario: ~/mnt/terraria.mario" +alias umg="umount ~/mnt/gaming-pc" +#alias ms="sshfs truenas.mario:/mnt/b8ce9a57-7ce7-47b8-a233-21184c8a0953/share ~/share -o reconnect -o ServerAliveInterval=15" +#alias ums="umount ~/share" +alias p="~/sh/ytmusicquick" +alias nas="ssh nas.mario" +#alias mn="sshfs -o allow_root truenas.mario:/mnt/mario ~/mnt/truenas.mario" +mn () { +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/share ~/mnt/truenas.mario/share +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/websites ~/mnt/truenas.mario/websites +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/roms ~/mnt/truenas.mario/roms +#sudo mount -o rsize=130048,wsize=131007,bsize=16777216,username=roms,password=00P9sVAgGQymKp2hZi79TYXliJt20tAT,uid=1000,gid=1000,iocharset=utf8,mapposix,actimeo=6,echo_interval=1,nostrictsync,cache=loose,nocase,soft,vers=3.1.1 -t cifs //10.0.21.1/roms ~/mnt/truenas.mario/roms +sudo mount --bind /home/lucka/.steam/steam/steamapps/compatdata /home/lucka/mnt/truenas.mario/roms/windows/Steamm/steamapps/compatdata +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/slowpool/movies ~/mnt/truenas.mario/movies +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/os-isos/template/iso ~/mnt/truenas.mario/os-isos +} +alias umn="sudo umount ~/mnt/truenas.mario/*" +alias mfs="~/sh/mount-all-filesystems.sh" +alias lgctl="~/sh/lgctl" +alias bs="barriers -f -c ~/.config/barrier-server.conf --disable-crypto" +alias xe="vim ~/.xmonad/xmonad.hs" +sshfs(){ +/usr/bin/sshfs -o reconnect,allow_root,workaround=buflimit,ServerAliveInterval=15,ServerAliveCountMax=3 $* +} +ytmp3 () { +yt-dlp --extract-audio --audio-format mp3 $@ +} +ytmp3numbered () { +ytmp3 --output "%(autonumber)s - %(title)s.%(ext)s" $@ +} +ytdl () { +yt-dlp "$*" +} +tfcfg () { +ssh gaming-win -t "e: && cd steamlibrary\steamapps\common\team fortress 2\tf\cfg && cmd" +} +gremote () { +#bash -c 'sleep 2 && remmina -c vnc://127.0.0.1:5901' & +ssh -L 5901:127.0.0.1:5901 $1 'pkill x11vnc; x11vnc -display :0 -rfbport 5901 -localhost -threads -noxfixes -noxdamage' +} +i () { +sudo apt install "$*" +} +u () { +sudo apt purge "$*" +} +sshmnt () { + mkdir -p ~/mnt/$1 + sshfs -o ServerAliveInterval=7 $1 ~/mnt/$1 +} +n () { + numlockx off +} +terminal-open () { + xfce4-terminal --command "$*" +} +topen () { + terminal-open "$*" +} ++x () { + chmod ug+x $* +} +cdwm () { + cd ~/compile/lukedwm/dwm +} +recordto () { + ffmpeg -f pulse -i default -codec:a flac "${1}.flac" +} +getclip () { + xclip -selection c -o +} +setclip () { + xclip -selection c +} +sshsus () { + ssh -J root@10.0.42.69 $* +} +webp () { + ffmpeg -i $1 -vcodec libwebp -filter:v fps=fps=60 -lossless 1 -loop 0 -preset default -an -vsync 0 $1.webp +} +alias py="python3" +pssh () { + adb forward tcp:65522 tcp:22; ssh root@127.0.0.1 -p 65522 $* +} +testvidmode () { + xrandr --delmode HDMI-A-0 $1 + xrandr --rmmode $1 + xrandr --newmode $* + xrandr --addmode HDMI-A-0 $1 + xrandr --output HDMI-A-0 --mode $1 +} +testvidmode2 () { + xrandr --delmode DisplayPort-0 $1 + xrandr --rmmode $1 + xrandr --newmode $* + xrandr --addmode DisplayPort-0 $1 + xrandr --output DisplayPort-0 --mode $1 +} +nintendontify () { + for i in *; do mkdir "$(echo $i | sed 's/.iso//')"; mv "$i" "$(echo $i | sed 's/.iso//')"/game.iso; done +} +wiiconnect () { + bluetoothctl connect 00:1E:35:3A:A9:B5 +} +vsync () { + picom --backend glx --vsync +} +crtTV () { +       testvidmode "1280x480_60i" 26.108 1280 1332 1455 1664 480 483 489 523 interlace -hsync -vsync +       xrandr --output DisplayPort-0 --mode 1280x480_60i --scale-from 640x480 --below HDMI-A-0 +} +crtTVscale () { +       testvidmode "1280x480_60i" 26.108 1280 1332 1455 1664 480 483 489 523 interlace -hsync -vsync +       xrandr --output DisplayPort-0 --mode 1280x480_60i --scale-from 1280x960 --below HDMI-A-0 +} + diff --git a/remove1280x960modes.sh b/remove1280x960modes.sh new file mode 100755 index 0000000..555533e --- /dev/null +++ b/remove1280x960modes.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +delMode () { + xrandr --delmode HDMI-A-0 "$1" + xrandr --rmmode "$1" +} + +for i in $(xrandr | grep -o '1280x960_[^ ]*') +do + delMode $i +done diff --git a/screenlayout/mirror900p.sh b/screenlayout/mirror900p.sh new file mode 100755 index 0000000..be34427 --- /dev/null +++ b/screenlayout/mirror900p.sh @@ -0,0 +1,4 @@ +#!/bin/bash +xrandr --newmode "1600x900_60p" 118.25 1600 1688 1856 2112 900 903 908 934 -hsync +vsync +xrandr --addmode DisplayPort-1 1600x900_60p +xrandr --output HDMI-A-0 --mode 1600x900_120i --primary --output DisplayPort-1 --mode 1600x900_60p --same-as HDMI-A-0 diff --git a/screenlayout/tv1080p.sh b/screenlayout/tv1080p.sh index 00379da..0c59e28 100755 --- a/screenlayout/tv1080p.sh +++ b/screenlayout/tv1080p.sh @@ -1,2 +1,2 @@ #!/bin/sh -xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off +xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode 1920x1080 --scale-from 1920x1080 --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off diff --git a/screenlayout/tv720p.sh b/screenlayout/tv720p.sh index a80627b..d48ca31 100755 --- a/screenlayout/tv720p.sh +++ b/screenlayout/tv720p.sh @@ -1,2 +1,5 @@ #!/bin/sh -xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode 1280x720 --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off +xrandr --newmode "1280x720_60.00" 74.50 1280 1344 1472 1664 720 723 728 748 -hsync +vsync +xrandr --addmode DisplayPort-1 "1280x720_60.00" + +xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode "1280x720_60.00" --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off diff --git a/vsyncToggle.sh b/vsyncToggle.sh new file mode 100755 index 0000000..5381b77 --- /dev/null +++ b/vsyncToggle.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Toggle picom with --backend glx --vsync + +if pgrep -x "picom" > /dev/null; then + # Picom is running → kill it + pkill -x picom + notify-send "Picom" "Compositor disabled" 2>/dev/null || true +else + # Picom is not running → start it + picom --backend glx --vsync & + notify-send "Picom" "Compositor enabled (GLX + VSync)" 2>/dev/null || true +fi