From 4b522caf5387f8075b7bbb2a2b0475c012157456 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 20 Aug 2016 02:03:56 +0300 Subject: [PATCH] almost --- .gitignore | 3 ++ Makefile | 1 + src/fbevents.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/fbevents.h | 13 +++++++++ src/fbgfx.c | 62 +++++++++++++++++++++++++++++++++++------ src/fbgfx.h | 3 ++ src/main.c | 62 +++++++++++++++++++++++++++++++++++++---- src/tunnel.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ src/tunnel.h | 8 ++++++ 9 files changed, 290 insertions(+), 14 deletions(-) create mode 100644 .gitignore create mode 100644 src/fbevents.c create mode 100644 src/fbevents.h create mode 100644 src/tunnel.c create mode 100644 src/tunnel.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1dded00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.d +fbgfx diff --git a/Makefile b/Makefile index 7882958..cf6bb9d 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ obj = $(src:.c=.o) bin = fbgfx CFLAGS = -pedantic -Wall -g +LDFLAGS = -limago -lm $(bin): $(obj) $(CC) -o $@ $(obj) $(LDFLAGS) diff --git a/src/fbevents.c b/src/fbevents.c new file mode 100644 index 0000000..1522a58 --- /dev/null +++ b/src/fbevents.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include "fbevents.h" + +static struct termios orig_state; +static int term_fd = -1; /* tty file descriptor */ + +static void (*keyb_func)(int, int, void*); +static void *keyb_cls; +static void (*mbutton_func)(int, int, int, int, void*); +static void *mbutton_cls; +static void (*mmotion_func)(int, int, void*); +static void *mmotion_cls; + + +int fbev_init(void) +{ + struct termios tstate; + + if((term_fd = open("/dev/tty", O_RDWR)) == -1) { + perror("failed to open tty"); + return -1; + } + fcntl(term_fd, F_SETFL, fcntl(term_fd, F_GETFL) | O_NONBLOCK); + + if(tcgetattr(term_fd, &tstate) == -1) { + perror("failed to retrieve tty attribs"); + close(term_fd); + return -1; + } + orig_state = tstate; + + cfmakeraw(&tstate); + if(tcsetattr(term_fd, TCSANOW, &tstate) == -1) { + close(term_fd); + return -1; + } + return 0; +} + +void fbev_shutdown(void) +{ + if(term_fd >= 0) { + tcsetattr(term_fd, TCSANOW, &orig_state); + close(term_fd); + term_fd = -1; + } +} + +void fbev_update(void) +{ + char buf[64]; + int i, sz; + assert(term_fd >= 0); + + while((sz = read(term_fd, buf, 64)) > 0) { + if(keyb_func) { + for(i=0; i #include +#include +#include #include #include #include @@ -14,6 +16,8 @@ static void *vmem; static int vmem_size; static struct fb_fix_screeninfo finfo; static struct fb_var_screeninfo vinfo; +static struct fb_var_screeninfo saved_vinfo; +static int saved_vinfo_valid; static int init(void) { @@ -42,10 +46,29 @@ static void cleanup(void) void *fbgfx_set_video_mode(int x, int y, int depth) { + struct fb_var_screeninfo new_vinfo; + if(init() == -1) { return 0; } - return 0; + + ioctl(fd, FBIOGET_VSCREENINFO, &new_vinfo); + new_vinfo.xres = x; + new_vinfo.yres = y; + new_vinfo.bits_per_pixel = depth; + + if(ioctl(fd, FBIOPUT_VSCREENINFO, &new_vinfo) == -1) { + fprintf(stderr, "failed to set video mode %dx%d %dbpp: %s\n", x, y, depth, strerror(errno)); + return 0; + } + + if(vmem) { + munmap(vmem, vmem_size); + vmem = 0; + vmem_size = 0; + } + + return fbgfx_get_video_mode(0, 0, 0); } void *fbgfx_get_video_mode(int *xptr, int *yptr, int *depthptr) @@ -53,18 +76,39 @@ void *fbgfx_get_video_mode(int *xptr, int *yptr, int *depthptr) if(init() == -1) { return 0; } - if(vmem) return vmem; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); vmem_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; - if((vmem = mmap(0, vmem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void*)-1) { - fprintf(stderr, "failed to map video memory\n"); - vmem = 0; - return 0; + if(!vmem) { + if((vmem = mmap(0, vmem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void*)-1) { + fprintf(stderr, "failed to map video memory\n"); + vmem = 0; + return 0; + } } - *xptr = vinfo.xres; - *yptr = vinfo.yres; - *depthptr = vinfo.bits_per_pixel; + if(xptr) *xptr = vinfo.xres; + if(yptr) *yptr = vinfo.yres; + if(depthptr) *depthptr = vinfo.bits_per_pixel; return vmem; } + +void fbgfx_save_video_mode(void) +{ + if(init() == -1) { + return; + } + + if(ioctl(fd, FBIOGET_VSCREENINFO, &saved_vinfo) == -1) { + return; + } + saved_vinfo_valid = 1; +} + +void fbgfx_restore_video_mode(void) +{ + if(init() == -1 || !saved_vinfo_valid) { + return; + } + ioctl(fd, FBIOPUT_VSCREENINFO, &saved_vinfo); +} diff --git a/src/fbgfx.h b/src/fbgfx.h index 6c18d7f..134de2f 100644 --- a/src/fbgfx.h +++ b/src/fbgfx.h @@ -4,5 +4,8 @@ void *fbgfx_set_video_mode(int x, int y, int depth); void *fbgfx_get_video_mode(int *xptr, int *yptr, int *depthptr); +void fbgfx_save_video_mode(void); +void fbgfx_restore_video_mode(void); + #endif /* FBGFX_H_ */ diff --git a/src/main.c b/src/main.c index 9d73367..8752567 100644 --- a/src/main.c +++ b/src/main.c @@ -1,19 +1,71 @@ #include -#include #include +#include #include "fbgfx.h" +#include "fbevents.h" +#include "tunnel.h" + +static void keyboard(int key, int pressed, void *cls); +static void mouse(int bn, int pressed, int x, int y, void *cls); +static void motion(int x, int y, void *cls); -static unsigned char *vmem; +static void *vmem; static int xsz, ysz, depth; +static int quit; + + int main(void) { - if(!(vmem = fbgfx_get_video_mode(&xsz, &ysz, &depth))) { + fbgfx_save_video_mode(); + if(!(vmem = fbgfx_set_video_mode(800, 600, 16))) { return 1; } - printf("current video mode: %dx%d %dbpp\n", xsz, ysz, depth); + fbgfx_get_video_mode(&xsz, &ysz, &depth); + if(depth != 16) { + goto end; + } + if(fbev_init() == -1) { + goto end; + } + fbev_keyboard(keyboard, 0); + fbev_mbutton(mouse, 0); + fbev_mmotion(motion, 0); + + if(init_tunnel(xsz, ysz) == -1) { + goto end; + } - /*memset(vmem, 0xff, xsz * ysz * depth / 8);*/ + for(;;) { + fbev_update(); + if(quit) break; + + draw_tunnel(vmem); + } +end: + destroy_tunnel(); + fbev_shutdown(); + fbgfx_restore_video_mode(); return 0; } + +static void keyboard(int key, int pressed, void *cls) +{ + if(!pressed) return; + + switch(key) { + case 27: + case 'q': + case 'Q': + exit(0); + } +} + +static void mouse(int bn, int pressed, int x, int y, void *cls) +{ +} + +static void motion(int x, int y, void *cls) +{ +} diff --git a/src/tunnel.c b/src/tunnel.c new file mode 100644 index 0000000..a348431 --- /dev/null +++ b/src/tunnel.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include "tunnel.h" + +static int xsz, ysz; +static unsigned int *tunnel_map; + + +int init_tunnel(int x, int y) +{ + int i, j; + unsigned int *tmap; + + xsz = x; + ysz = y; + + printf("precalculating tunnel map...\n"); + + if(!(tunnel_map = malloc(xsz * ysz * sizeof *tunnel_map))) { + fprintf(stderr, "failed to allocate tunnel map\n"); + return -1; + } + tmap = tunnel_map; + + for(i=0; i> 16) & 0xffff; + unsigned int ty = *tmap & 0xffff; + ++tmap; + + r = tx >> 8; + g = ty >> 8; + + *pixels++ = ((((r >> 3) & 0x1f) << 11) | + (((g >> 2) & 0x3f) << 5));/* | + ((b >> 3) & 0x1f));*/ + } + } +} diff --git a/src/tunnel.h b/src/tunnel.h new file mode 100644 index 0000000..c4337e1 --- /dev/null +++ b/src/tunnel.h @@ -0,0 +1,8 @@ +#ifndef TUNNEL_H_ +#define TUNNEL_H_ + +int init_tunnel(int x, int y); +void destroy_tunnel(void); +void draw_tunnel(unsigned short *pixels); + +#endif /* TUNNEL_H_ */ -- 1.7.10.4