shithub: cursedfs

ref: 113de1e06a4945445ce898388092b174fe40f2ba
dir: /screen.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <event.h>
#include "fs.h"

void moveball(void);
void initball(void);

Image *ball;

Point p;
Font *ourfont;
Image *brush;
Rune *s = L"☺☹σπß";

/* Menus */
char *buttons[] = {"exit", 0};
Menu menu = { buttons };

/* Radius of ball */
int r = 20;
int borderWidth = 4;



/* Change direction of ball if collision
 * else move the ball and draw to screen
 * The new ball image draws over the previous image
 * so there is no need to redraw the whole screen */

void
moveball()
{

	Point out;
	out = runestring(
			screen, screen->r.min, display->black, ZP,
		    ourfont, s
	);
	flushimage(display, 1);
}



/* Graphics library requires this function */

void
eresized(int new)
{
	if(new && getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");

	/* Store new screen coordinates for collision detection */
	p = Pt(Dx(screen->r), Dy(screen->r));

	/* Draw the background DWhite */
	draw(screen, insetrect(screen->r, borderWidth), 
			allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DWhite), 
			nil, ZP);
}


// Center font rendering at a point?
// from faces(1)
/*
void
center(Font *f, Point p, char *s, Image *color)
{
	int i, n, dx;
	Rune rbuf[32];
	char sbuf[32*UTFmax+1];

	dx = stringwidth(f, s);
	if(dx > Facesize){
		n = torune(rbuf, s, nelem(rbuf));
		for(i=0; i<n; i++){
			dx = runestringnwidth(f, rbuf, i+1);
			if(dx > Facesize)
				break;
		}
		sprint(sbuf, "%.*S", i, rbuf);
		s = sbuf;
		dx = stringwidth(f, s);
	}
	p.x += (Facesize-dx)/2;
	string(screen, p, color, ZP, f, s);
}
*/

/* Draw red ball inside a square of white background
 * When ball is drawn at new position, background will
 * blot out the previous image */

void
initball()
{
	Point out;
	ourfont = openfont(display, "/lib/font/bit/vga/unicode.font");

	p = runestringsize(ourfont, s);

	out = runestring(
			screen, screen->r.min, display->black, ZP,
		    ourfont, s
	);
}


void
initscreen(void*)
{
	Event ev;
	int e, timer;

	/* Initiate graphics and mouse */
	if(initdraw(nil, nil, "cursedfs") < 0)
		sysfatal("initdraw failed: %r");

	einit(Emouse);

	/* Start our timer
	 * move the ball every 5 milliseconds
	 * unless there is an Emouse event */

	timer = etimer(0, 5);

	/* Simulate a resize event to draw the background
	 * and acquire the screen dimensions */

	eresized(0);

	initball();

	/* Main event loop */

	for(;;){
		e = event(&ev);

		/* If there is a mouse event, the rightmost button
		 * pressed and the first menu option selected
		 * then exit.. */

		if( (e == Emouse) &&
			(ev.mouse.buttons & 4) && 
			(emenuhit(3, &ev.mouse, &menu) == 0)) threadexitsall(nil);
		else 
			if(e == timer)
				moveball();
	}
}