Rework ovo,owo,uwu scripts, to now compile the source code on launch.
This commit is contained in:
1
.local/.gitignore
vendored
1
.local/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/share/*
|
||||
!/share/cpusetcores
|
||||
!/share/dvd.c
|
||||
|
||||
15
.local/bin/dvd
Executable file
15
.local/bin/dvd
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Get the executable location, following xdg-state spec.
|
||||
exe=$XDG_STATE_HOME
|
||||
[ -z "$exe" ] && exe=$HOME/.local/state
|
||||
exe+=/dvd
|
||||
|
||||
# Compile the executable
|
||||
[ -x "$exe" ] || {
|
||||
src="$(dirname "$0")/../share/dvd.c"
|
||||
cc -s -std=gnu99 -Os -o "$exe" "$src"
|
||||
}
|
||||
|
||||
# Continue executing the executable
|
||||
exec -a "$(basename "$0")" "$exe" "$@"
|
||||
BIN
.local/bin/ovo
BIN
.local/bin/ovo
Binary file not shown.
1
.local/bin/ovo
Symbolic link
1
.local/bin/ovo
Symbolic link
@@ -0,0 +1 @@
|
||||
dvd
|
||||
BIN
.local/bin/owo
BIN
.local/bin/owo
Binary file not shown.
1
.local/bin/owo
Symbolic link
1
.local/bin/owo
Symbolic link
@@ -0,0 +1 @@
|
||||
dvd
|
||||
BIN
.local/bin/uwu
BIN
.local/bin/uwu
Binary file not shown.
1
.local/bin/uwu
Symbolic link
1
.local/bin/uwu
Symbolic link
@@ -0,0 +1 @@
|
||||
dvd
|
||||
121
.local/share/dvd.c
Normal file
121
.local/share/dvd.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Fixed integer size type definitions. */
|
||||
typedef __INT8_TYPE__ i8;
|
||||
typedef __INT16_TYPE__ i16;
|
||||
typedef __INT32_TYPE__ i32;
|
||||
typedef __INT64_TYPE__ i64;
|
||||
typedef __UINT8_TYPE__ u8;
|
||||
typedef __UINT16_TYPE__ u16;
|
||||
typedef __UINT32_TYPE__ u32;
|
||||
typedef __UINT64_TYPE__ u64;
|
||||
|
||||
/* Variable integer sizes. */
|
||||
typedef signed long long llong;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
static const char *formats[3] = {
|
||||
"\033[1K" // Erase from start of the line to the cursor
|
||||
"\033[%d;%dH" // Set cursor to row and column (origin 1,1)
|
||||
"\033[9%dm%s", // Set colour and print text.
|
||||
|
||||
"\033[%d;%dH" // Set cursor to row and column (origin 1,1)
|
||||
"\033[9%dm%s", // Set colour and print text.
|
||||
|
||||
"\033[%d;%dH" // Set cursor to row and column (origin 1,1)
|
||||
"\033[1K" // Erase from start of the line to the cursor
|
||||
"\033[9%dm%s", // Set colour and print text.
|
||||
};
|
||||
|
||||
static const char *owo = "owo\0";
|
||||
static const char *uwu = "uwu\0";
|
||||
static const char *ovo = "ovo\0";
|
||||
|
||||
static void cursor_pos(int *row, int *col)
|
||||
{
|
||||
/* Disable echo and canonical mode,
|
||||
* So LF isn't needed to continue execution, and so the value isn't printed. */
|
||||
tcflag_t flag;
|
||||
struct termios term;
|
||||
tcgetattr(STDIN_FILENO, &term);
|
||||
flag = term.c_lflag;
|
||||
term.c_lflag &= ~(ICANON | ECHO); // Disable echo and canonical mode
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &term);
|
||||
|
||||
/* Acquire the cursor position(s). */
|
||||
fprintf(stderr, "\033[6n");
|
||||
getchar(); // ESC
|
||||
getchar(); // [
|
||||
char c;
|
||||
*row = 0;
|
||||
*col = 0;
|
||||
while ((c = getchar()) != ';')
|
||||
*row = (*row * 10) + (c - '0');
|
||||
while ((c = getchar()) != 'R')
|
||||
*col = (*col * 10) + (c - '0');
|
||||
|
||||
/* Restore the previous flags. */
|
||||
term.c_lflag = flag;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &term);
|
||||
}
|
||||
|
||||
/*
|
||||
* INFO: Beware the fmt parameter, since it may break. */
|
||||
static void dvd(const char *fmt, const char *txt)
|
||||
{
|
||||
u8 colour = 0;
|
||||
int x, dx = -1;
|
||||
int y, dy = 1;
|
||||
_Bool tmpx, tmpy;
|
||||
cursor_pos(&y, &x);
|
||||
fprintf(stderr, "\033[?25l"); // Hide cursor
|
||||
|
||||
ushort w, h;
|
||||
{
|
||||
struct winsize ws;
|
||||
ioctl(STDERR_FILENO, TIOCGWINSZ, &ws);
|
||||
w = ws.ws_col - 2;
|
||||
h = ws.ws_row;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* test for collisions. */
|
||||
tmpx = (1 < x) & (x < w);
|
||||
tmpy = (1 < y) & (y < h);
|
||||
|
||||
/* flip direction if that axis has collided. */
|
||||
dx = tmpx ? dx : -dx;
|
||||
dy = tmpy ? dy : -dy;
|
||||
colour = (colour + !(tmpx & tmpy)) & 7; // increment colour on collisions
|
||||
|
||||
/* Write the message */
|
||||
fprintf(stderr,
|
||||
fmt,
|
||||
y, x,
|
||||
colour, txt);
|
||||
|
||||
/* Increment the co-ordinate, and ensure it remains within bounds. */
|
||||
x += dx;
|
||||
y += dy;
|
||||
|
||||
usleep(50 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Perform slightly different actions, depending on arg0. */
|
||||
if (!argc) return 1;
|
||||
if (!strncmp(*argv, owo, 4)) dvd(formats[0], owo);
|
||||
if (!strncmp(*argv, uwu, 4)) dvd(formats[1], uwu);
|
||||
if (!strncmp(*argv, ovo, 4)) dvd(formats[2], ovo);
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user