~henesy/smolvm

e02005fd4328186a108c9da0003573ebb0a3026a — henesy 51 years ago 6c02ffc
draw in a separate proc ;; use channel for updating pixels
2 files changed, 107 insertions(+), 19 deletions(-)

M main.c
M plan9_gui.c
M main.c => main.c +4 -3
@@ 1,5 1,6 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
#include "svm.h"

int chatty;				// Verbose debug output


@@ 14,9 15,9 @@ usage(void)
}

void
main(int argc, char *argv[])
threadmain(int argc, char *argv[])
{
	uint width = 24;
	uint width = 25;

	ARGBEGIN{
	case 'D':


@@ 54,5 55,5 @@ main(int argc, char *argv[])
	
	sleep(20000);

	exits(nil);
	threadexitsall(nil);
}

M plan9_gui.c => plan9_gui.c +103 -16
@@ 1,16 1,25 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <keyboard.h>
#include "svm.h"

/* devdraw notes
/* 

== draw(3) notes 

Global variables:

- screen
- display

== event(2) notes

Global functions to be called passively:

- eresized()

*/

/* draw a line through the middle of the window


@@ 27,6 36,13 @@ Global variables:
#define BLACK	0xFFFFFFFF
#define WHITE	0x000000FF

// Represents a colored coordinate on the pixel grid
typedef struct Coordinate Coordinate;
struct Coordinate {
	Point;
	Image*		color;
};

// Single pixel images
Image *black;
Image *white;


@@ 37,6 53,7 @@ Screen	*scr;
Image	*disp;
uint	width;

Channel *pixchan;	// For setting individual pixels on the screen

// Resize the window to our screen size
void


@@ 53,6 70,66 @@ resize(void)
	close(fd);
}

// Manage and draw the screen passively
void
drawer(void *v)
{
	Channel *pixchan = (Channel*)v;
	print("drawer start\n");

	int y, x;
	Image ***pixels;

	pixels = calloc(width, sizeof (Image**));
	for(y = 0; y < width; y++){
		pixels[y] = calloc(width, sizeof (Image*));
		for(x = 0; x < width; x++)
			pixels[y][x] = bg;
	}

	Coordinate pix;

	Alt alts[] = {
		{pixchan, &pix, CHANRCV},
		{nil, nil, CHANEND},
	};

	// Draw loop
	for(;;){
		// Check for new pixels

		switch(alt(alts)){
		case 0:
			recv(pixchan, &pix);
			pixels[pix.y][pix.x] = pix.color;
			break;

		// TODO - force draw chan?

		default:
			// TODO - sleep?
			break;
		}

		// Draw all pixels
		for(y = 0; y < width; y++)
			for(x = 0; x < width; x++){
				Point p = mulpt((Point){x, y}, scale);
	
				Point tl = addpt(screen->r.min, p);
				Point br = addpt(tl, (Point){scale, scale});
	
				Rectangle r = (Rectangle){tl, br};

				Image *c = pixels[y][x];

				draw(disp, r, c, nil, p);
				flushimage(screen->display, 0);
			}

		sleep(1);
	}
}

// Init rio window
void


@@ 63,13 140,14 @@ startgui(uint w)
	resize();

	if(initdraw(nil, nil, "smolvm") < 0)
		sysfatal("initdraw: %r");

		sysfatal("err: could not initdraw - %r");

	// Allocate images for later use
	bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, BGCOLOR);
	black = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, BLACK);
	white = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, WHITE);
	
	// Initialize and draw out the rio window
	scr = allocscreen(screen, bg, 0);
	
	disp = allocwindow(scr, screen->r, 0, BGCOLOR);


@@ 77,6 155,11 @@ startgui(uint w)
	draw(screen, screen->r, bg, nil, ZP);
	
	flushimage(display, 1);

	pixchan = chancreate(sizeof (Coordinate), 0);
	proccreate(drawer, pixchan, 4096);

	return;
}




@@ 90,18 173,22 @@ drawpx(uint x, uint y, int on)
	Image *c = white;
	if(on)
		c = black;
		
	Point p = mulpt((Point){x, y}, scale);
	
	//int winheight = screen->r.max.y - screen->r.min.y;
	//int winwidth = screen->r.max.x - screen->r.min.x;
	
	Point tl = addpt(screen->r.min, p);
	Point br = addpt(tl, (Point){scale, scale});
	
	Rectangle r = (Rectangle){tl, br};

	Coordinate *pix = calloc(1, sizeof (Coordinate));
	*pix = (Coordinate){(Point){x,y}, c};

	send(pixchan, pix);
}

// Called by event(2) on screen resize events
void
eresized(int new)
{
	if(new && getwindow(display, Refnone) < 0)
		sysfatal("err: can't reattach to window after resize - %r");
	
	draw(disp, r, c, nil, p);
	// TODO - draw the screen forcefully
	
	flushimage(screen->display, 0);
}
\ No newline at end of file
	//flushimage(screen->display, 0);
	resize();
}