diff -urN wf-/Makefile wf/Makefile --- wf-/Makefile Fri Dec 11 00:00:00 2015 +++ wf/Makefile Sat Dec 12 00:00:00 2015 @@ -3,7 +3,7 @@ LIBS = -lm -lX11 -L/usr/X11R6/lib CFLAGS += -Wall -I/usr/X11R6/include -WF_OBJS = wf_ex.o eye.o d3.o x.o util.o +WF_OBJS = wf_ex.o eye.o d3.o x.o util.o key.o select.o all: wf_ex diff -urN wf-/eye.c wf/eye.c --- wf-/eye.c Fri Dec 11 00:00:00 2015 +++ wf/eye.c Sat Dec 12 00:00:00 2015 @@ -18,6 +18,9 @@ d3_set(&wh[3], -e->w/2, e->len, -e->h/2); d3_set(&o, 0,0,0); for(i=0; i<4; i++) plane_set(&e->clip[i], &o, &wh[i], &wh[(i+1)%4]); + + e->move_deg = 1; + e->zoom_rate = 0.1; } void @@ -57,4 +60,26 @@ chg |= ret; } return chg; /* bit 0 : a moved , bit 1 : b moved */ +} + +void +eye_move(eye_t *e, int mode, int h_v, int dir) +{ + line_t l; + + if(mode == 2){ /* zoom */ + double t = 1 - e->zoom_rate; + + line_set(&l, &e->t, &e->p); + line_pos(&l, dir > 0 ? t : 1 / t, &e->p); + return; + } + + /* mode == 0 or 1 */ + + l.v = h_v == 'h' ? e->ax.z : e->ax.x; + if(h_v == 'v') d3_mul(&l.v, -1); + + l.p = mode == 0 ? e->t : e->p; + pos_rot(mode == 0 ? &e->p : &e->t, &l, e->move_deg * dir); } diff -urN wf-/eye.h wf/eye.h --- wf-/eye.h Fri Dec 11 00:00:00 2015 +++ wf/eye.h Sat Dec 12 00:00:00 2015 @@ -8,6 +8,8 @@ int sx, ex, sy, ey; pos_t p, t; + double move_deg, zoom_rate; + plane_t clip[4]; axis_t ax; } eye_t; @@ -16,5 +18,6 @@ void eye_update(eye_t *e); int eye_conv(const eye_t *e, const pos_t *p, int *rx, int *ry); int eye_clip(const eye_t *e, pos_t *a, pos_t *b); +void eye_move(eye_t *e, int mode, int h_v, int dir); #endif diff -urN wf-/key.c wf/key.c --- wf-/key.c Thu Jan 1 09:00:00 1970 +++ wf/key.c Sun Apr 13 22:00:00 2014 @@ -0,0 +1,121 @@ +#include "key.h" +#include "select.h" +#include +#include +#include +#include +#include +#include + +#define KEY_FD 0 + +static struct termios bak; +fd_set cui_key_fds; + +void +cui_key_init(void) +{ + FD_ZERO(&cui_key_fds); +} + +void +cui_key_enter(void) +{ + struct termios raw; + + tcgetattr(KEY_FD, &bak); + cfmakeraw(&raw); + raw.c_lflag &= ~FLUSHO; + tcsetattr(KEY_FD, TCSANOW, &raw); +} + +void +cui_key_exit(void) +{ + tcsetattr(KEY_FD, TCSANOW, &bak); +} + +void +cui_key_fd_add(int fd) +{ + FD_SET(fd, &cui_key_fds); + cui_select_add(fd); +} + +void +cui_key_fd_del(int fd) +{ + FD_CLR(fd, &cui_key_fds); + cui_select_del(fd); +} + +int +cui_key_fd_chk(int fd) +{ + return FD_ISSET(fd, &cui_key_fds); +} + +int +cui_key_get(void) +{ + unsigned char uc; + + if(!cui_select_readable_chk(KEY_FD, 100*1000)) return 0; + if(read(KEY_FD, &uc, 1) != 1) return 0; + return uc; +} + +void +cui_key_fd_close(void) /* without KEY_FD (0) */ +{ + int fd; + for(fd=1; fd= FD_SETSIZE) return 0; + + k = key_get(fd); + if(k == 0x7f) return CUI_KEY_BS; + if(k == CUI_KEY_ESC){ + k2 = key_get(fd); + if(k2 == '['){ + k3 = key_get(fd); + switch(k3){ + case 'A': return CUI_KEY_UP; + case 'B': return CUI_KEY_DOWN; + case 'C': return CUI_KEY_RIGHT; + case 'D': return CUI_KEY_LEFT; + } + } + } + return k; +} + +/* EOF */ diff -urN wf-/key.h wf/key.h --- wf-/key.h Thu Jan 1 09:00:00 1970 +++ wf/key.h Sun Apr 13 22:00:00 2014 @@ -0,0 +1,31 @@ +#ifndef __KEY_H__ +#define __KEY_H__ + +#include /* for fd_set */ +#include + +#define CUI_KEY_ENTER 0x0d /* '\r' */ +#define CUI_KEY_BS 0x08 /* '\b' */ +#define CUI_KEY_CTRL(c) (0x01+(c)-'A') +#define CUI_KEY_UP CUI_KEY_CTRL('P') +#define CUI_KEY_DOWN CUI_KEY_CTRL('N') +#define CUI_KEY_LEFT CUI_KEY_CTRL('B') +#define CUI_KEY_RIGHT CUI_KEY_CTRL('F') +#define CUI_KEY_ESC 0x1b + +void cui_key_init(void); +void cui_key_enter(void); +void cui_key_exit(void); + +extern fd_set cui_key_fds; +void cui_key_fd_add(int fd); +void cui_key_fd_del(int fd); +int cui_key_fd_chk(int fd); +void cui_key_fd_close(void); /* without KEY_FD (0) */ + +int cui_key_get(void); +int cui_key_get2(void); + +extern int cui_key_last_fd; + +#endif diff -urN wf-/select.c wf/select.c --- wf-/select.c Thu Jan 1 09:00:00 1970 +++ wf/select.c Sat Apr 12 23:00:00 2014 @@ -0,0 +1,60 @@ +#include "select.h" +#include +#include +#include +#include +#include + +static fd_set sel_rfs, res_rfs; + +void +cui_select_init(void) +{ + FD_ZERO(&sel_rfs); +} + +void +cui_select_add(int fd) +{ + FD_SET(fd, &sel_rfs); +} + +void +cui_select_del(int fd) +{ + FD_CLR(fd, &sel_rfs); +} + +int +cui_select(int usec) +{ + int nfds = 0, fd; + struct timeval tm; + + res_rfs = sel_rfs; + for(fd=0; fd nfds) nfds = fd; + tm.tv_sec = 0; + tm.tv_usec = usec; + return select(nfds+1, &res_rfs, NULL, NULL, &tm); +} + +int +cui_select_chk(int fd) +{ + return FD_ISSET(fd, &res_rfs); +} + +int +cui_select_readable_chk(int fd, int usec) +{ + fd_set rfs; + struct timeval tm; + + FD_ZERO(&rfs); + FD_SET(fd, &rfs); + tm.tv_sec = 0; + tm.tv_usec = usec; + return select(fd+1, &rfs, NULL, NULL, &tm) > 0; +} + +/* EOF */ diff -urN wf-/select.h wf/select.h --- wf-/select.h Thu Jan 1 09:00:00 1970 +++ wf/select.h Sat Apr 12 23:00:00 2014 @@ -0,0 +1,12 @@ +#ifndef __SELECT_H__ +#define __SELECT_H__ + +void cui_select_init(void); +void cui_select_add(int fd); +void cui_select_del(int fd); +int cui_select(int usec); +int cui_select_chk(int fd); + +int cui_select_readable_chk(int fd, int usec); + +#endif diff -urN wf-/wf_ex.c wf/wf_ex.c --- wf-/wf_ex.c Fri Dec 11 00:00:00 2015 +++ wf/wf_ex.c Sat Dec 12 00:00:00 2015 @@ -1,23 +1,92 @@ +#include +#include "key.h" #include "x.h" #include "eye.h" +static int +key_work(eye_t *e, int *mode) +{ + switch(cui_key_get2()){ + case 'q': + return EOF; + case ' ': + case CUI_KEY_ENTER: + *mode = (*mode + 1) % 3; + break; + case CUI_KEY_UP: + eye_move(e, *mode, 'v', 1); + break; + case CUI_KEY_DOWN: + eye_move(e, *mode, 'v', -1); + break; + case CUI_KEY_LEFT: + eye_move(e, *mode, 'h', -1); + break; + case CUI_KEY_RIGHT: + eye_move(e, *mode, 'h', 1); + break; + default: + usleep(100*1000); + break; + } + return 0; +} + void -draw_line(eye_t *e, pos_t *p) +draw_line(const eye_t *e, const pos_t *p) { + pos_t p2[2]; int i, x[2], y[2]; - for(i=0; i<2; i++) axis_conv(&e->ax, &p[i]); - if(eye_clip(e, &p[0], &p[1]) < 0) return; - for(i=0; i<2; i++) eye_conv(e, &p[i], &x[i], &y[i]); + p2[0] = p[0]; + p2[1] = p[1]; + for(i=0; i<2; i++) axis_conv(&e->ax, &p2[i]); + if(eye_clip(e, &p2[0], &p2[1]) < 0) return; + for(i=0; i<2; i++) eye_conv(e, &p2[i], &x[i], &y[i]); if(x[0] == x[1] && y[0] == y[1]) return; xline(x[0], y[0], x[1], y[1]); } +void +draw_pyramid_sample(const eye_t *e, int n, int mode) +{ + pos_t p[5], add; + int i; + + d3_set(&p[0], -1, -1, 0); + d3_set(&p[1], 1, -1, 0); + d3_set(&p[2], 1, 1, 0); + d3_set(&p[3], -1, 1, 0); + d3_set(&p[4], 0, 0, 1 - mode); + + n--; + d3_set(&add, n*0.5, n*0.5, n*0.2); + for(i=0; i<5; i++){ + d3_mul(&p[i], n*0.2); + d3_add(&p[i], &add); + } + for(i=0; i<4; i++){ + pos_t p2[2]; + + p2[0] = p[i]; + p2[1] = p[(i+1)%4]; + draw_line(e, p2); + + p2[1] = p[4]; + draw_line(e, p2); + } +} + int main(int ac, char **av) { int w, h, i, n = opt_int("-n", ac, av, 10); eye_t eye; + int mode = 0; + + cui_key_init(); + cui_key_fd_add(0); + cui_key_enter(); xinit(ac, av, &w, &h); if(opt_idx("-ximg", ac, av) > 0) ximg_curr = ximg_alloc(); @@ -25,25 +94,28 @@ eye_init(&eye, w, h); d3_set(&eye.p, 0, -n, n); d3_set(&eye.t, n/2, n/2, 0); - eye_update(&eye); - xclear(); - for(i=0; i