ref: b0e0ff38a15e54a4763831d94543dffa1341f417
dir: /screen.c/
#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() { /* static Point bp={6, 6}; // Ball Position static double Δi=4, Δj=4; // Collision detection if(bp.x > p.x - (r*3) || bp.x < -r) Δi = Δi*-1; if(bp.y > p.y - (r*3) || bp.y < -r) Δj = Δj*-1; // Increment ball position bp.x = bp.x + Δi; bp.y = bp.y + Δj; draw(screen, rectaddpt(screen->r, bp), ball, nil, ZP); */ Point out = runestring( screen, p, 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); //brush = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DBlack); out = runestring( screen, p, display->black, ZP, ourfont, s ); flushimage(display, 1); //sysfatal("%d %d\n", p.x, p.y); /* ball=allocimage(display, (Rectangle){(Point){0,0},(Point){r*4,r*4}}, screen->chan, 0, DWhite); fillellipse(ball, (Point){r*2,r*2}, r, r, brush, ZP); */ } 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(); } }