-
Notifications
You must be signed in to change notification settings - Fork 0
/
tunnel.c
69 lines (61 loc) · 2.06 KB
/
tunnel.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>
#include <stdlib.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
int main() {
int fb = open("/dev/fb0", O_RDWR);
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
ioctl(fb, FBIOGET_FSCREENINFO, &finfo);
ioctl(fb, FBIOGET_VSCREENINFO, &vinfo);
vinfo.grayscale = 0;
vinfo.bits_per_pixel = 32;
ioctl(fb, FBIOPUT_VSCREENINFO, &vinfo);
long screensize = vinfo.yres_virtual * finfo.line_length;
uint32_t *fbp = mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fb, (off_t)0);
uint32_t x, y;
uint32_t width = finfo.line_length / 4, height = vinfo.yres;
uint32_t yoff = vinfo.yoffset, xoff = vinfo.xoffset;
uint32_t *d = malloc(screensize);
uint32_t *a = malloc(screensize);
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
int32_t relx = x - width / 2, rely = -(y - height / 2);
double angle = atan2(rely, relx);
uint32_t u, v;
v = (uint32_t)(((angle / M_PI) + 1.0) * height / 2.0);
u = (uint32_t)(width * 16 / sqrt(relx * relx + rely * rely)) %
width;
uint32_t pos = (y + yoff) * width + (x + xoff);
d[pos] = u;
a[pos] = v;
}
}
uint32_t *texture = malloc(screensize);
memcpy(texture, fbp, screensize);
uint32_t *backbuffer = calloc(screensize, 1);
int t;
for (t = 0;; t++) {
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
uint32_t pos = (y + yoff) * width + (x + xoff);
uint32_t u = (d[pos] + t) % height;
uint32_t v = (a[pos] + t) % height;
uint32_t col = texture[(v + yoff) * width + (u + xoff)];
backbuffer[pos] = col;
}
}
memcpy(fbp, backbuffer, screensize);
usleep(16);
}
return 0;
}