Add video testing program for fun
This commit is contained in:
@@ -7,7 +7,8 @@ CC=x86_64-elf-yggdrasil-gcc
|
||||
DIRS=$(O) \
|
||||
$(STAGE) \
|
||||
$(O)/sh \
|
||||
$(O)/ase
|
||||
$(O)/ase \
|
||||
$(O)/vsh
|
||||
HDRS=$(shell find $(S) -type f -name "*.h")
|
||||
STAGE_BIN=$(STAGE)/init \
|
||||
$(STAGE)/bin/hexd \
|
||||
@@ -24,7 +25,8 @@ STAGE_BIN=$(STAGE)/init \
|
||||
$(STAGE)/bin/netctl \
|
||||
$(STAGE)/bin/netmeow \
|
||||
$(STAGE)/bin/netdump \
|
||||
$(STAGE)/bin/video
|
||||
$(STAGE)/bin/mouse \
|
||||
$(STAGE)/bin/vsh
|
||||
|
||||
# $(STAGE)/bin/com \
|
||||
# $(STAGE)/bin/ase \
|
||||
@@ -35,6 +37,11 @@ sh_OBJS=$(O)/sh/sh.o \
|
||||
$(O)/sh/builtin.o \
|
||||
$(O)/sh/cmd.o
|
||||
ase_OBJS=$(O)/ase/ase.o
|
||||
vsh_OBJS=$(O)/vsh/vsh.o \
|
||||
$(O)/vsh/input.o \
|
||||
$(O)/vsh/video.o \
|
||||
$(O)/vsh/font.o \
|
||||
$(O)/vsh/logo.o
|
||||
|
||||
usr_CFLAGS=-ggdb \
|
||||
-msse \
|
||||
@@ -75,9 +82,17 @@ $(STAGE)/bin/%: core/bin/%.c
|
||||
$(STAGE)/bin/sh: $(sh_OBJS)
|
||||
$(CC) -o $@ $(usr_LDFLAGS) $(sh_OBJS)
|
||||
|
||||
$(STAGE)/bin/vsh: $(vsh_OBJS)
|
||||
$(CC) -o $@ $(usr_LDFLAGS) $(vsh_OBJS)
|
||||
|
||||
$(STAGE)/bin/ase: $(ase_OBJS)
|
||||
$(CC) -o $@ $(usr_LDFLAGS) $(ase_OBJS)
|
||||
|
||||
$(O)/vsh/%.o: vsh/%.c $(shell find vsh -name "*.h")
|
||||
$(CC) -c -o $@ $(usr_CFLAGS) $<
|
||||
$(O)/vsh/%.o: vsh/%.S
|
||||
$(CC) -c -o $@ $(usr_CFLAGS) $<
|
||||
|
||||
$(O)/sh/%.o: sh/%.c $(shell find sh -name "*.h")
|
||||
$(CC) -c -o $@ $(usr_CFLAGS) $<
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
static int running = 1;
|
||||
|
||||
static int mx = 40;
|
||||
static int my = 12;
|
||||
static double mx_d = 40, my_d = 12;
|
||||
|
||||
static int con_width, con_height;
|
||||
|
||||
static void signal_handle(int signum) {
|
||||
running = 0;
|
||||
}
|
||||
|
||||
static void kb_handle(char *buf, size_t len) {
|
||||
if (buf[0] == 'q') {
|
||||
running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ms_handle(char *buf, size_t len) {
|
||||
for (size_t i = 0; i < len / 5; ++i) {
|
||||
char type = buf[i * 5 + 0];
|
||||
|
||||
switch (type) {
|
||||
case 'd': {
|
||||
int16_t dx = *(int16_t *) &buf[i * 5 + 1];
|
||||
int16_t dy = *(int16_t *) &buf[i * 5 + 3];
|
||||
|
||||
mx_d += (double) dx / 4.0;
|
||||
my_d -= (double) dy / 12.0;
|
||||
|
||||
if (mx_d < 0) {
|
||||
mx_d = 0;
|
||||
}
|
||||
if (mx_d >= con_width - 1) {
|
||||
mx_d = con_width - 2;
|
||||
}
|
||||
|
||||
if (my_d < 0) {
|
||||
my_d = 0;
|
||||
}
|
||||
if (my_d >= con_height - 1) {
|
||||
my_d = con_height - 2;
|
||||
}
|
||||
|
||||
mx = mx_d;
|
||||
my = my_d;
|
||||
puts2("\033[2J\033[1;1f");
|
||||
printf("\033[%d;%dfX\033[%d;%df", my + 1, mx + 1, my + 1, mx + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
struct termios old_ts, ts;
|
||||
struct winsize winsz;
|
||||
int kb_fd = STDIN_FILENO, ms_fd;
|
||||
char buf[512];
|
||||
ssize_t len;
|
||||
|
||||
signal(SIGINT, signal_handle);
|
||||
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &winsz) != 0) {
|
||||
perror("ioctl()");
|
||||
return -1;
|
||||
}
|
||||
printf("Terminal is %dx%d\n", winsz.ws_col, winsz.ws_row);
|
||||
con_width = winsz.ws_col;
|
||||
con_height = winsz.ws_row;
|
||||
if (tcgetattr(kb_fd, &old_ts) != 0) {
|
||||
perror("tcgetattr()");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&ts, &old_ts, sizeof(struct termios));
|
||||
ts.c_iflag &= ~ICANON;
|
||||
ts.c_lflag = 0;
|
||||
if (tcsetattr(kb_fd, TCSANOW, &ts) != 0) {
|
||||
perror("tcsetattr()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ms_fd = open("/dev/ps2aux", O_RDONLY, 0);
|
||||
|
||||
while (running) {
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(ms_fd, &fds);
|
||||
FD_SET(kb_fd, &fds);
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int res = select(ms_fd + 1, &fds, NULL, NULL, &tv);
|
||||
|
||||
if (res < 0) {
|
||||
perror("select()");
|
||||
break;
|
||||
}
|
||||
|
||||
if (res != 0) {
|
||||
if (FD_ISSET(ms_fd, &fds)) {
|
||||
len = read(ms_fd, buf, sizeof(buf));
|
||||
ms_handle(buf, len);
|
||||
}
|
||||
if (FD_ISSET(kb_fd, &fds)) {
|
||||
len = read(kb_fd, buf, sizeof(buf));
|
||||
kb_handle(buf, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tcsetattr(kb_fd, TCSANOW, &old_ts) != 0) {
|
||||
perror("tcsetattr()");
|
||||
return -1;
|
||||
}
|
||||
printf("Stopped\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
+175
-27
@@ -1,6 +1,8 @@
|
||||
#include <ygg/video.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
@@ -8,16 +10,119 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
static int running = 1;
|
||||
static double mx_d = 40, my_d = 12;
|
||||
|
||||
static uint8_t cursor[8] = {
|
||||
0b11111111,
|
||||
0b11111110,
|
||||
0b11111100,
|
||||
0b11111000,
|
||||
0b11110000,
|
||||
0b11100000,
|
||||
0b11000000,
|
||||
0b10000000,
|
||||
};
|
||||
|
||||
static uint32_t *vmem;
|
||||
static size_t vsize;
|
||||
|
||||
static void signal_handler(int signum) {
|
||||
running = 0;
|
||||
}
|
||||
|
||||
static void ms_handle(char *buf, size_t len) {
|
||||
for (size_t i = 0; i < len / 5; ++i) {
|
||||
char type = buf[i * 5 + 0];
|
||||
|
||||
switch (type) {
|
||||
case 'd': {
|
||||
int16_t dx = *(int16_t *) &buf[i * 5 + 1];
|
||||
int16_t dy = *(int16_t *) &buf[i * 5 + 3];
|
||||
|
||||
mx_d += (double) dx / 4.0;
|
||||
my_d -= (double) dy / 6.0;
|
||||
|
||||
if (mx_d < 0) {
|
||||
mx_d = 0;
|
||||
}
|
||||
if (mx_d >= mode.width - 1) {
|
||||
mx_d = mode.width - 2;
|
||||
}
|
||||
|
||||
if (my_d < 0) {
|
||||
my_d = 0;
|
||||
}
|
||||
if (my_d >= mode.height - 1) {
|
||||
my_d = mode.height - 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rect(int x0, int y0, int x1, int y1, uint32_t col) {
|
||||
for (int x = MAX(x0, 0); x <= MIN(x1, mode.width - 1); ++x) {
|
||||
for (int y = MAX(y0, 0); y <= MIN(y1, mode.height - 1); ++y) {
|
||||
vmem[y * mode.width + x] = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_cursor(int x, int y, uint32_t col) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (i + x >= mode.width) {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
if (j + y >= mode.height) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(cursor[j] & (1 << (7 - i)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vmem[(j + y) * mode.width + x + i] = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void render(void) {
|
||||
static double px, py;
|
||||
|
||||
rect(px, py, px + 8, py + 8, 0);
|
||||
|
||||
px = mx_d;
|
||||
py = my_d;
|
||||
|
||||
draw_cursor(px, py, 0xFF0000);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct ioc_vmode mode;
|
||||
int fd = open("/dev/fb0", O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
int mouse_fd = open("/dev/ps2aux", O_RDONLY, 0);
|
||||
struct termios tc, tc_old;
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
char buf[512];
|
||||
ssize_t len;
|
||||
int no = 0;
|
||||
|
||||
tc.c_iflag = 0;
|
||||
tc.c_lflag = 0;
|
||||
tc.c_oflag = 0;
|
||||
|
||||
if (tcgetattr(STDIN_FILENO, &tc_old) != 0) {
|
||||
perror("tcgetattr()");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (fd < 0 || mouse_fd < 0) {
|
||||
perror("open()");
|
||||
return -1;
|
||||
}
|
||||
@@ -27,55 +132,98 @@ int main(int argc, char **argv) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tc) != 0) {
|
||||
perror("tcsetattr()");
|
||||
goto end;
|
||||
}
|
||||
|
||||
signal(SIGINT, signal_handler);
|
||||
|
||||
printf("Video mode: %dx%d\n", mode.width, mode.height);
|
||||
|
||||
size_t size = mode.width * mode.height * 4;
|
||||
size = (size + 0xFFF) & ~0xFFF;
|
||||
printf("%u bytes\n", size);
|
||||
vsize = mode.width * mode.height * 4;
|
||||
vsize = (vsize + 0xFFF) & ~0xFFF;
|
||||
printf("%u bytes\n", vsize);
|
||||
|
||||
printf("You can exit by pressing ^C\n");
|
||||
printf("Starting video in 3 secs\n");
|
||||
usleep(3000000);
|
||||
printf("Starting video in 1 sec\n");
|
||||
usleep(1000000);
|
||||
|
||||
if (!running) {
|
||||
// Interrupt happened
|
||||
close(mouse_fd);
|
||||
close(fd);
|
||||
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tc_old) != 0) {
|
||||
perror("tcsetattr()");
|
||||
goto end;
|
||||
}
|
||||
|
||||
puts2("\033[2J\033[1;1f");
|
||||
printf("Goodbye\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int no = 0;
|
||||
if (ioctl(fd, IOC_FBCON, &no) != 0) {
|
||||
perror("ioctl()");
|
||||
goto end;
|
||||
}
|
||||
|
||||
uint32_t *data = mmap(NULL, size, 0, MAP_PRIVATE, fd, 0);
|
||||
assert(data);
|
||||
vmem = mmap(NULL, vsize, 0, MAP_PRIVATE, fd, 0);
|
||||
assert(vmem);
|
||||
|
||||
struct timeval tv;
|
||||
int c = 0;
|
||||
int s = 0;
|
||||
memset(vmem, 0, vsize);
|
||||
|
||||
while (running) {
|
||||
usleep(10000);
|
||||
gettimeofday(&tv, NULL);
|
||||
if (s == 0) {
|
||||
c += 2;
|
||||
} else {
|
||||
c -= 2;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(mouse_fd, &fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
|
||||
int res = select(mouse_fd + 1, &fds, NULL, NULL, &tv);
|
||||
|
||||
if (res < 0) {
|
||||
no = 1;
|
||||
if (ioctl(fd, IOC_FBCON, &no) != 0) {
|
||||
perror("ioctl()");
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("select() failed\n");
|
||||
|
||||
break;
|
||||
}
|
||||
if (c < 0) {
|
||||
s = 0;
|
||||
c = 0;
|
||||
} else if (c >= 256) {
|
||||
s = 1;
|
||||
c = 255;
|
||||
|
||||
if (res > 0) {
|
||||
if (FD_ISSET(mouse_fd, &fds)) {
|
||||
len = read(mouse_fd, buf, sizeof(buf));
|
||||
ms_handle(buf, len);
|
||||
}
|
||||
if (FD_ISSET(STDIN_FILENO, &fds)) {
|
||||
read(STDIN_FILENO, buf, sizeof(buf));
|
||||
|
||||
if (buf[0] == 'q') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
memset(data, c, size);
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
munmap(data, size);
|
||||
munmap(vmem, vsize);
|
||||
no = 1;
|
||||
if (ioctl(fd, IOC_FBCON, &no) != 0) {
|
||||
perror("ioctl()");
|
||||
goto end;
|
||||
}
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tc_old) != 0) {
|
||||
perror("tcsetattr()");
|
||||
goto end;
|
||||
}
|
||||
|
||||
puts2("\033[2J\033[1;1f");
|
||||
printf("Goodbye\n");
|
||||
end:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
.section .text
|
||||
.global font_start
|
||||
.global font_end
|
||||
|
||||
.align 4
|
||||
font_start:
|
||||
.incbin "vsh/font.psfu"
|
||||
font_end:
|
||||
Binary file not shown.
+127
@@ -0,0 +1,127 @@
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
|
||||
static fd_set input_fds;
|
||||
static struct termios tc_old, tc;
|
||||
static struct timeval input_tv;
|
||||
static int keyboard_fd = STDIN_FILENO;
|
||||
static int mouse_fd;
|
||||
int cursor_x = 0, cursor_y = 0;
|
||||
|
||||
void cursor_move(int16_t dx, int16_t dy) {
|
||||
cursor_x += dx;
|
||||
cursor_y -= dy;
|
||||
|
||||
if (cursor_x < 0) {
|
||||
cursor_x = 0;
|
||||
} else if (cursor_x >= fb_mode.width) {
|
||||
cursor_x = fb_mode.width - 1;
|
||||
}
|
||||
if (cursor_y < 0) {
|
||||
cursor_y = 0;
|
||||
} else if (cursor_y >= fb_mode.height) {
|
||||
cursor_y = fb_mode.height - 1;
|
||||
}
|
||||
}
|
||||
|
||||
int input_wait_event(struct input_event *ev) {
|
||||
int res;
|
||||
ssize_t len;
|
||||
char buf[128];
|
||||
|
||||
FD_ZERO(&input_fds);
|
||||
FD_SET(keyboard_fd, &input_fds);
|
||||
FD_SET(mouse_fd, &input_fds);
|
||||
input_tv.tv_sec = 0;
|
||||
input_tv.tv_usec = 10000;
|
||||
|
||||
res = select(mouse_fd + 1, &input_fds, NULL, NULL, &input_tv);
|
||||
|
||||
if (res < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (res > 0) {
|
||||
if (FD_ISSET(keyboard_fd, &input_fds)) {
|
||||
// Read a single key event
|
||||
len = read(keyboard_fd, buf, 1);
|
||||
|
||||
if (len < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ev->type = IN_KEY_DOWN;
|
||||
ev->key = buf[0];
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (FD_ISSET(mouse_fd, &input_fds)) {
|
||||
len = read(mouse_fd, buf, 5);
|
||||
|
||||
if (len != 5) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char type = buf[0];
|
||||
|
||||
switch (type) {
|
||||
case 'd':
|
||||
ev->type = IN_MOUSE_MOVE;
|
||||
ev->mouse_move.dx = *(int16_t *) &buf[1];
|
||||
ev->mouse_move.dy = *(int16_t *) &buf[3];
|
||||
cursor_move(ev->mouse_move.dx, ev->mouse_move.dy);
|
||||
return 1;
|
||||
case 'b':
|
||||
ev->type = buf[3] ? IN_BUTTON_DOWN : IN_BUTTON_UP;
|
||||
ev->button = buf[1];
|
||||
return 1;
|
||||
default:
|
||||
// Skip unknown events
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int input_init(void) {
|
||||
if (tcgetattr(keyboard_fd, &tc_old)) {
|
||||
perror("tcgetattr()");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&tc, &tc_old, sizeof(struct termios));
|
||||
// No canonical mode
|
||||
tc.c_iflag &= ~ICANON;
|
||||
// No echo
|
||||
tc.c_lflag = 0;
|
||||
|
||||
if (tcsetattr(keyboard_fd, TCSANOW, &tc) != 0) {
|
||||
perror("tcsetattr()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mouse_fd = open("/dev/ps2aux", O_RDONLY, 0);
|
||||
|
||||
if (mouse_fd < 0) {
|
||||
perror("open(/dev/ps2aux)");
|
||||
// Restore old terminal behavior
|
||||
tcsetattr(keyboard_fd, TCSANOW, &tc_old);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void input_close(void) {
|
||||
tcsetattr(keyboard_fd, TCSANOW, &tc_old);
|
||||
close(mouse_fd);
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#define BUTTON_LEFT 1
|
||||
|
||||
struct input_event {
|
||||
enum {
|
||||
IN_KEY_DOWN,
|
||||
IN_BUTTON_DOWN,
|
||||
IN_BUTTON_UP,
|
||||
IN_MOUSE_MOVE,
|
||||
} type;
|
||||
union {
|
||||
char key;
|
||||
struct {
|
||||
int16_t dx, dy;
|
||||
} mouse_move;
|
||||
int button;
|
||||
};
|
||||
};
|
||||
|
||||
extern int cursor_x, cursor_y;
|
||||
|
||||
int input_wait_event(struct input_event *ev);
|
||||
int input_init(void);
|
||||
void input_close(void);
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
|
||||
/* GIMP header image file format (RGB): /home/alnyan/Documents/logo.h */
|
||||
char *font_logo_header_data =
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
":76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
":76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
":76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F"
|
||||
":76F:76F:76F````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F"
|
||||
":76F:76F````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F"
|
||||
":76F:76F````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F"
|
||||
":76F````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F````"
|
||||
"````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F"
|
||||
"````````````````````````````:76F:76F:76F:76F:76F:76F:76F````````"
|
||||
"````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!"
|
||||
"!!!!!!!!`Q!!`Q!!`Q!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F"
|
||||
"````````````````````````````:76F:76F:76F:76F:76F:76F:76F````````"
|
||||
"````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F`Q!!"
|
||||
"`Q!!`Q!!`Q!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F"
|
||||
"````````!!!!!!!!````````````:76F:76F:76F:76F:76F:76F:76F````````"
|
||||
"!!!!!!!!````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F`Q!!"
|
||||
"`Q!!`Q!!C!!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F````"
|
||||
"````````!!!!!!!!````````````````:76F:76F:76F:76F:76F````````````"
|
||||
"!!!!!!!!````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"C!!!C!!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F````````"
|
||||
"````````!!!!!!!!````````````````````:76F:76F:76F````````````````"
|
||||
"!!!!!!!!````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"`Q!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F````````"
|
||||
"````````!!!!!!!!````````````````````:76F:76F:76F````````````````"
|
||||
"!!!!!!!!````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"`Q!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F````````"
|
||||
"````````!!!!!!!!````````````````````:76F:76F:76F````````````````"
|
||||
"!!!!!!!!````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"C!!!C!!!!!!!`Q!!`Q!!`Q!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F````"
|
||||
"````````````````````````````````:76F:76F:76F:76F:76F````````````"
|
||||
"````````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"`Q!!`Q!!`Q!!`Q!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"````````````````````````````:76F:76F:76F:76F:76F:76F:76F````````"
|
||||
"````````````````````:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
"`Q!!`Q!!C!!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F`Q!!"
|
||||
"C!!!C!!!`Q!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76FC!!!"
|
||||
"`Q!!`Q!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F`Q!!`Q!!"
|
||||
"`Q!!`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F`Q!!`Q!!"
|
||||
"`Q!!C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76FC!!!C!!!C!!!"
|
||||
"C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F`Q!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76F:76F:76F:76F:76F`Q!!`Q!!`Q!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`Q!!"
|
||||
"C!!!C!!!C!!!:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F:76F"
|
||||
":76F:76F:76FC!!!C!!!C!!!`Q!!`Q!!`Q!!`Q!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`Q!!"
|
||||
"C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!"
|
||||
"C!!!C!!!C!!!C!!!C!!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`Q!!`Q!!"
|
||||
"`Q!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!"
|
||||
"C!!!C!!!C!!!C!!!`Q!!`Q!!`Q!!`Q!!C!!!`Q!!`Q!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`Q!!`Q!!"
|
||||
"`Q!!`Q!!`Q!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!"
|
||||
"C!!!C!!!C!!!`Q!!`Q!!`Q!!`Q!!C!!!`Q!!`Q!!`Q!!`Q!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`Q!!`Q!!C!!!"
|
||||
"`Q!!`Q!!`Q!!`Q!!`Q!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!C!!!"
|
||||
"C!!!`Q!!`Q!!`Q!!`Q!!`Q!!C!!!`Q!!`Q!!`Q!!`Q!!`Q!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`Q!!`Q!!`Q!!"
|
||||
"C!!!C!!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!"
|
||||
"`Q!!`Q!!`Q!!`Q!!`Q!!C!!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`Q!!`Q!!`Q!!"
|
||||
"`Q!!`Q!!C!!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!"
|
||||
"`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!`Q!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"";
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#define FONT_LOGO_WIDTH 64
|
||||
#define FONT_LOGO_HEIGHT 64
|
||||
|
||||
#define FONT_LOGO_HEADER_PIXEL(data,pixel) {\
|
||||
pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
|
||||
pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
|
||||
pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
|
||||
data += 4; \
|
||||
}
|
||||
|
||||
extern char *font_logo_header_data;
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define PSF_FONT_MAGIC 0x864ab572
|
||||
|
||||
struct psf_font {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t headersize;
|
||||
uint32_t flags;
|
||||
uint32_t numglyph;
|
||||
uint32_t bytesperglyph;
|
||||
uint32_t height;
|
||||
uint32_t width;
|
||||
};
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
#include "video.h"
|
||||
#include "psf.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <ygg/video.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Framebuffer
|
||||
static int fb;
|
||||
static size_t fb_size;
|
||||
static uint32_t *fb_mem;
|
||||
static uint16_t fb_charw, fb_charh;
|
||||
struct ioc_vmode fb_mode;
|
||||
|
||||
// PSF font
|
||||
static struct psf_font *font;
|
||||
static uintptr_t psf_fb_addr, psf_fb_pitch;
|
||||
|
||||
int psf_init(uintptr_t addr, uintptr_t pitch, uint16_t *charw, uint16_t *charh);
|
||||
|
||||
void video_putpixel(size_t x, size_t y, uint32_t v) {
|
||||
fb_mem[y * fb_mode.width + x] = v;
|
||||
}
|
||||
|
||||
int video_start(void) {
|
||||
int off = 0;
|
||||
|
||||
if ((fb = open("/dev/fb0", O_RDONLY, 0)) < 0) {
|
||||
perror("open(/dev/fb0)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get framebuffer size
|
||||
if (ioctl(fb, IOC_GETVMODE, &fb_mode) != 0) {
|
||||
perror("ioctl(IOC_GETVMODE)");
|
||||
close(fb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fb_size = (fb_mode.width * fb_mode.height * 4 + 0xFFF) & ~0xFFF;
|
||||
|
||||
// Lock framebuffer
|
||||
if (ioctl(fb, IOC_FBCON, &off) != 0) {
|
||||
perror("ioctl(IOC_FBCON = off)");
|
||||
close(fb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Map framebuffer into memory
|
||||
if ((fb_mem = mmap(NULL, fb_size, 0, MAP_PRIVATE, fb, 0)) == MAP_FAILED) {
|
||||
perror("mmap()");
|
||||
// Unlock framebuffer for cleanup
|
||||
off = 1;
|
||||
if (ioctl(fb, IOC_FBCON, &off) != 0) {
|
||||
perror("ioctl(IOC_FBCON = off)");
|
||||
close(fb);
|
||||
return -1;
|
||||
}
|
||||
close(fb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
psf_init((uintptr_t) fb_mem, fb_mode.width * 4, &fb_charw, &fb_charh);
|
||||
memset(fb_mem, 0, fb_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void video_stop(void) {
|
||||
int on = 1;
|
||||
ioctl(fb, IOC_FBCON, &on);
|
||||
munmap(fb_mem, fb_size);
|
||||
close(fb);
|
||||
}
|
||||
|
||||
extern char font_start;
|
||||
|
||||
int psf_init(uintptr_t addr, uintptr_t pitch, uint16_t *charw, uint16_t *charh) {
|
||||
font = (struct psf_font *) &font_start;
|
||||
if (font->magic != PSF_FONT_MAGIC) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
psf_fb_addr = addr;
|
||||
psf_fb_pitch = pitch;
|
||||
|
||||
*charw = font->width;
|
||||
*charh = font->height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void video_draw_string(size_t x, size_t y, const char *str, uint32_t fg) {
|
||||
for (; *str; x += fb_charw, ++str) {
|
||||
video_draw_glyph(y, x, *str, fg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void video_draw_glyph(uint16_t row, uint16_t col, uint8_t c, uint32_t fg, uint32_t bg) {
|
||||
if (c >= font->numglyph) {
|
||||
c = 0;
|
||||
}
|
||||
|
||||
int bytesperline = (font->width + 7) / 8;
|
||||
|
||||
uint8_t *glyph = (uint8_t *) &font_start + font->headersize + c * font->bytesperglyph;
|
||||
// XXX: Assuming BPP is 32
|
||||
/* calculate the upper left corner on screen where we want to display.
|
||||
we only do this once, and adjust the offset later. This is faster. */
|
||||
uintptr_t offs = (row * psf_fb_pitch) + (col * 4);
|
||||
/* finally display pixels according to the bitmap */
|
||||
uint32_t x, y, line, mask;
|
||||
for (y = 0; y < font->height; ++y) {
|
||||
/* save the starting position of the line */
|
||||
line = offs;
|
||||
mask = 1 << (font->width - 1);
|
||||
/* display a row */
|
||||
for (x = 0; x < font->width; ++x) {
|
||||
*((uint32_t *)(psf_fb_addr + line)) = ((int) *glyph) & (mask) ? fg : bg;
|
||||
/* adjust to the next pixel */
|
||||
mask >>= 1;
|
||||
line += 4;
|
||||
}
|
||||
/* adjust to the next line */
|
||||
glyph += bytesperline;
|
||||
offs += psf_fb_pitch;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <ygg/video.h>
|
||||
|
||||
extern struct ioc_vmode fb_mode;
|
||||
|
||||
void video_putpixel(size_t x, size_t y, uint32_t v);
|
||||
void video_draw_glyph(uint16_t row, uint16_t col, uint8_t c, uint32_t fg, uint32_t bg);
|
||||
void video_draw_string(size_t x, size_t y, const char *str, uint32_t fg);
|
||||
|
||||
int video_start(void);
|
||||
void video_stop(void);
|
||||
@@ -0,0 +1,165 @@
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "logo.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
static int running = 1;
|
||||
|
||||
static void signal_handler(int signum) {
|
||||
running = 0;
|
||||
}
|
||||
|
||||
static void draw_logo(int x, int y) {
|
||||
char pixel[4];
|
||||
char *data = font_logo_header_data;
|
||||
uint32_t v;
|
||||
for (uint32_t j = y; j < y + FONT_LOGO_HEIGHT; ++j) {
|
||||
for (uint32_t i = x; i < x + FONT_LOGO_WIDTH; ++i) {
|
||||
FONT_LOGO_HEADER_PIXEL(data, pixel);
|
||||
v = pixel[2] | ((uint32_t) pixel[1] << 8) | ((uint32_t) pixel[0] << 16);
|
||||
if (v) {
|
||||
video_putpixel(i, j, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_cursor(int x, int y) {
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
for (size_t j = 0; j < 8; ++j) {
|
||||
if (x + i >= fb_mode.width ||
|
||||
y + j >= fb_mode.height) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (7 - j > i) {
|
||||
video_putpixel(x + i, y + j, 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t get_time(void) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
static void draw_progress(size_t count, size_t total) {
|
||||
size_t w = count * fb_mode.width / total;
|
||||
|
||||
for (size_t i = 0; i < fb_mode.width; ++i) {
|
||||
for (size_t j = fb_mode.height - 16; j < fb_mode.height; ++j) {
|
||||
video_putpixel(i, j, i <= w ? 0x00FF00 : 0xCCCCCC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define CLICK_COUNT_EXIT 20
|
||||
int main(int argc, char **argv) {
|
||||
struct input_event ev;
|
||||
int prev_x = 0, prev_y = 0;
|
||||
int logo_vel_x = 1, logo_vel_y = 1;
|
||||
double logo_x = 0, logo_y = 0;
|
||||
int click_count = 0;
|
||||
int err = 0;
|
||||
int res;
|
||||
|
||||
signal(SIGINT, signal_handler);
|
||||
|
||||
if (input_init() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (video_start() != 0) {
|
||||
input_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t t0, t, dt;
|
||||
|
||||
t0 = get_time();
|
||||
|
||||
while (running) {
|
||||
t = get_time();
|
||||
dt = t - t0;
|
||||
|
||||
res = input_wait_event(&ev);
|
||||
|
||||
if (res < 0) {
|
||||
err = errno;
|
||||
break;
|
||||
}
|
||||
|
||||
if (res == 1) {
|
||||
// An event ocurred
|
||||
if (ev.type == IN_KEY_DOWN && ev.key == 'q') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ev.type == IN_KEY_DOWN || ev.type == IN_BUTTON_UP) {
|
||||
++click_count;
|
||||
|
||||
if (click_count == CLICK_COUNT_EXIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t x = (int) logo_x; x < (int) logo_x + FONT_LOGO_WIDTH; ++x) {
|
||||
for (size_t y = (int) logo_y; y < (int) logo_y + FONT_LOGO_HEIGHT; ++y) {
|
||||
video_putpixel(x, y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
t0 = t;
|
||||
logo_x += logo_vel_x * ((double) dt / 10);
|
||||
logo_y += logo_vel_y * ((double) dt / 10);
|
||||
|
||||
if (logo_x < 0) {
|
||||
logo_vel_x = 1;
|
||||
logo_x = 0;
|
||||
} else if (logo_x + FONT_LOGO_WIDTH >= fb_mode.width) {
|
||||
logo_vel_x = -1;
|
||||
logo_x = fb_mode.width - FONT_LOGO_WIDTH - 1;
|
||||
}
|
||||
if (logo_y < 0) {
|
||||
logo_vel_y = 1;
|
||||
logo_y = 0;
|
||||
} else if (logo_y + FONT_LOGO_HEIGHT >= fb_mode.height) {
|
||||
logo_vel_y = -1;
|
||||
logo_y = fb_mode.height - FONT_LOGO_HEIGHT - 1;
|
||||
}
|
||||
|
||||
draw_logo(logo_x, logo_y);
|
||||
draw_progress(click_count, CLICK_COUNT_EXIT);
|
||||
|
||||
video_draw_string(100, 100, "Test?", 0xFF0000);
|
||||
|
||||
for (size_t x = prev_x; x < MIN(prev_x + 8, fb_mode.width); ++x) {
|
||||
for (size_t y = prev_y; y < MIN(prev_y + 8, fb_mode.height); ++y) {
|
||||
video_putpixel(x, y, 0);
|
||||
}
|
||||
}
|
||||
draw_cursor(cursor_x, cursor_y);
|
||||
prev_x = cursor_x;
|
||||
prev_y = cursor_y;
|
||||
}
|
||||
|
||||
video_stop();
|
||||
input_close();
|
||||
puts2("\033[2J\033[1;1f");
|
||||
|
||||
if (err) {
|
||||
printf("An error ocurred: %s\n", strerror(err));
|
||||
} else {
|
||||
printf("Execution finished normally\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user