shithub: catvclock

ref: 0430a5300ee18b367865bdd497d7982973abf578
dir: /main.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <keyboard.h>
#include <mouse.h>

Mousectl *mctl;
Keyboardctl *kctl;

Image *body, *tail, *eyes;
Point offset;
float tailoffset = 0.0f;
float tailspeed = 1.0f;
float eyesoffset = 0.0f;
float eyesspeed = 0.5f;

int round(double x){
	return x>=0.?x+.5:x-.5;
}

void
drawhand(int length, int width, double theta)
{
	double c=cos(theta), s=sin(theta);
	double ws=width*s, wc=width*c;
	Point vhand[4];
	vhand[0]=addpt(screen->r.min, addpt(offset, Pt(78+round(length*s), 240-round(length*c))));
	vhand[1]=addpt(screen->r.min, addpt(offset, Pt(78-round(ws+wc), 240+round(wc-ws))));
	vhand[2]=addpt(screen->r.min, addpt(offset, Pt(78-round(ws-wc), 240+round(wc+ws))));
	vhand[3] = vhand[0];
	fillpoly(screen, vhand, 4, 1, display->white, 
		addpt(screen->r.min, vhand[0]));
	poly(screen, vhand, 4, Endsquare, Endsquare, 0, display->black,
		addpt(screen->r.min, vhand[0]));
}

void
drawstuff(void)
{
	Point p;
	Tm tm = *localtime(time(0));

	draw(screen, screen->r, display->white, nil, ZP);
	p.x = -(offset.x + tailoffset);
	p.y = -offset.y;
	draw(screen, screen->r, tail, nil, p);
	p.x = -offset.x;
	p.y = -offset.y;
	draw(screen, screen->r, body, nil, p);
	p.x = -(offset.x + eyesoffset);
	draw(screen, screen->r, eyes, nil, p);

	drawhand(50, 6, 2.*PI*tm.min/60.);
	drawhand(30, 6, 2.*PI*(tm.hour+tm.min/60.)/12.);
	flushimage(display, 1);
}

void
kbthread(void *arg)
{
	Keyboardctl *kc = arg;
	Rune r;

	for(;;){
		recv(kc->c, &r);
		switch(r){
		case Kdel:
		case Kesc:
		case 'q':
			threadexitsall(nil);
		}
		drawstuff();
	}
}

void
mthread(void*)
{
	Mouse m;
	for(;;){
		recv(mctl->c, &m);
	}
}
void
resthread(void *arg)
{
	Mousectl *mc = arg;
	for(;;){
		recvul(mc->resizec);
		if(getwindow(display, Refnone) < 0)
			sysfatal("getwindow: %r");
		print("resize\n");
		offset.x = (Dx(screen->r)-Dx(body->r))/2;
		offset.y = (Dy(screen->r)-Dy(body->r))/2;
		drawstuff();
	}
}

void
init(void)
{
	int fd;

	fd = open("body.bit", OREAD);
	if(fd < 0)
		sysfatal("open: %r");
	body = readimage(display, fd, 0);
	close(fd);

	fd = open("tail.bit", OREAD);
	if(fd < 0)
		sysfatal("open: %r");
	tail = readimage(display, fd, 0);
	close(fd);

	fd = open("eyes.bit", OREAD);
	if(fd < 0)
		sysfatal("open: %r");
	eyes = readimage(display, fd, 0);
	close(fd);

	print("read imgs\n");

	offset.x = (Dx(screen->r)-Dx(body->r))/2;
	offset.y = (Dy(screen->r)-Dy(body->r))/2;
}

void
threadmain(int, char *argv[])
{
	kctl = initkeyboard("/dev/cons");
	if(kctl == nil)
		sysfatal("initkeyboard: %r");
	mctl = initmouse("/dev/mouse", screen);
	if(mctl == nil)
		sysfatal("initmouse: %r");

	if(initdraw(nil, nil, argv[0]) < 0)
		sysfatal("initdraw: %r");

	threadcreate(mthread, nil, mainstacksize);
	threadcreate(kbthread, kctl, 8*1024);
	threadcreate(resthread, mctl, 8*1024);

	init();

	drawstuff();
	while(1){
		sleep(12);
		tailoffset += tailspeed;
		eyesoffset += eyesspeed;
		if(tailoffset > 15.0f || tailoffset < -15.0f){
			tailspeed *= -1.0f;
			eyesspeed *= -1.0f;
		}
		drawstuff();
		yield();
	}
}