#include <errno.h>
#include <regex.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
int match(const char *string, char *pattern) {
int status;
regex_t re;
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) {
return(0);
}
status = regexec(&re, string, (size_t) 0, NULL, 0);
regfree(&re);
if (status != 0) {
return(0);
}
return(1);
}
void clstdin() {
int stdincp = dup(STDIN_FILENO);
tcdrain(stdincp);
tcflush(stdincp, TCIFLUSH);
close(stdincp);
}
int startpipe(char *path, char *input , char *output, ssize_t *size) {
int fd0[2];
int fd1[2];
pid_t pid;
if (pipe(fd0) < 0 || pipe(fd1) < 0) {
fprintf(stderr, "Error occured when piping.\n");
return -2;
}
if ((pid = fork()) < 0) {
fprintf(stderr, "Error occured when forking.\n");
return -3;
} else if (pid == 0) {
close(fd0[1]);
close(fd1[0]);
if (fd0[0] != STDIN_FILENO) {
if (dup2(fd0[0], STDIN_FILENO) != STDIN_FILENO)
fprintf(stderr, "Error occured while duplicating stdin.\n");
close(fd0[0]);
}
if (fd1[1] != STDOUT_FILENO) {
if (dup2(fd1[1], STDOUT_FILENO) != STDOUT_FILENO)
fprintf(stderr, "Error occured while duplicating stdout.\n");
close(fd1[1]);
}
if (path == NULL)
fprintf(stderr, "oof, yet even more errors, this time with getcwd.\n");
if (execl(path, "clld", (char *)0) < 0) {
fprintf(stderr, "System error has occured.\n");
return -4;
}
return 0;
} else {
int status;
close(fd0[0]);
close(fd1[1]);
write(fd0[1], input, strlen(input));
while (pid = waitpid(pid, &status, WUNTRACED) > 0) {
if (pid == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status)) {
printf("\033[10;1H\033[2Kchild exited, status=%d", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("\033[10;1H\033[2Kchild killed (signal %d)", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
printf("\033[10;1H\033[2Kchild stopped (signal %d)", WSTOPSIG(status));
} else {
printf("\033[10;1H\033[2KUnexpected status (0x%x)", status);
}
}
close(fd0[1]);
*size = read(fd1[0], output, 129);
close(fd1[0]);
return 0;
}
return 0;
}
void split(char *str, char **splitstr) {
char *p;
int i=0;
p = strtok(str,"\n");
while(p!= NULL) {
splitstr[i] = malloc(strlen(p) + 1);
if (splitstr[i])
strcpy(splitstr[i], p);
i++;
p = strtok (NULL, "\n");
}
}
int main (int argc, char **argv) {
uint8_t u = 0, d = 0, l = 0;
uint8_t r = 0;
int frame = 0;
double x1 = 224, y1 = 128;
int w1 = 16, h1 = 16;
double xvel = 0, yvel = 0;
int x2 = 256, y2 = 256;
int w2 = 64, h2 = 64;
int stat;
char *keys;
char *buf = malloc(8193);
FILE *fp;
fp = popen("actkbd -Ps", "r");
printf("\033[2J");
if (fp == NULL) {
fprintf(stderr, "Error occured when trying to run actkbd.\n");
free(buf);
return 1;
}
while (fgets(buf, 8193, fp) != NULL) {
ssize_t size = 0;
char *tmp = malloc(4096);
char *input = malloc(2049);
char *path = malloc(4102);
char ln[129];
frame = atoi(strtok(buf, " "));
keys = strtok(NULL, " ");
for(int ch = 0; ch<sizeof(ln); ch++)
ln[ch] = '\0';
sprintf(path, "%s/clld", getcwd(tmp, 4096));
sprintf(input, "1\n%i,%i\n%i,%i\n%07.06f,%07.06f\n%i,%i\n%i,%i\n", w1, h1, (int)x1, (int)y1, xvel, yvel, w2, h2, x2, y2);
startpipe(path, input, &ln, &size);
char *line[65] = {NULL};
split(ln, line);
x1 = atof(strtok(line[2], ","));
y1 = atof(strtok(NULL, "\0"));
xvel = atof(strtok(line[3], ","));
yvel = atof(strtok(NULL, "\0"));
u = match(keys, "KEY_W");
d = (match(keys, "KEY_S") && !match(keys, "KEY_(SHIFT|SLASH|SPACE|SEMICOLON)"));
l = match(keys, "KEY_A") && !match(keys,"KEY_APOSTROPHE");
r = (match(keys, "KEY_D") && !match(keys, "KEY_(DOWN|DELETE|DOT)"));
(u) ? (yvel-=0.25) : ((yvel < 0) ? (d ? (yvel+=0.5) : (yvel+=0.25)) : (yvel=yvel));
(d) ? (yvel+=0.25) : ((yvel > 0) ? (u ? (yvel-=0.5) : (yvel-=0.25)) : (yvel=yvel));
(l) ? (xvel-=0.25) : ((xvel < 0) ? (r ? (xvel+=0.5) : (xvel+=0.25)) : (xvel=xvel));
(r) ? (xvel+=0.25) : ((xvel > 0) ? (l ? (xvel-=0.5) : (xvel-=0.25)) : (xvel=xvel));
yvel = (yvel > 5) ? 5 : (yvel < -5 ? -5 : yvel);
xvel = (xvel > 5) ? 5 : (xvel < -5 ? -5 : xvel);
x1+=xvel;
y1+=yvel;
printf("\033[1;1H\033[2K%s", keys);
printf(
"\033[E\033[2Kframe: %i, u: %u, d: %u, l: %u, r: %u"
"\033[E\033[2Kx1: %i, y1: %i"
"\033[E\033[2Kxvel: %07.06f, yvel: %07.06f"
"\n\033[2K", frame, u, d, l, r, (int)x1, (int)y1, xvel, yvel);
if (match(keys, "KEY_Q")) {
printf("\033[2J\033[1;1H");
free(buf);
free(tmp);
free(path);
free(input);
clstdin();
clstdin();
return 0;
}
free(tmp);
free(path);
free(input);
}
free(buf);
}