shithub: pain

Download patch

ref: 892668527d0e1f705ab39c7da828c54d9dc4cc6e
parent: 434c6ce50a65ecfdfc4e537edbb2ed4f50da6312
author: jmq <jmq@jmq.sh>
date: Sat Dec 7 18:06:21 EST 2024

fix gameloop and inputs

--- a/bindings.c
+++ b/bindings.c
@@ -26,8 +26,12 @@
 static void
 BindingStroke(int e)
 {
-	if (e != BEenter)
+	if (e == BEleave)
+	{
+		if (CurrentLayer != nil)
+			CurrentLayer->changed = 1;
 		return;
+	}
 
 	stroke();
 }
@@ -55,16 +59,28 @@
 BindingMoveCanvas(int e)
 {
 	static int movetask = -1;
+	if (e == BEenter)
+		MoveMark = MousePosition;
+	else if (e == BEleave) {
+		CanvasAt = addpt(CanvasAt, subpt(MousePosition, MoveMark));
+		CanvasMoved = DrawAllLayers = 1;
+	}
+}
+
+static void
+BindingClearLayer(int e)
+{
 	if (e != BEenter)
 		return;
-	MoveMark = MousePosition;
-	removetask(movetask);
-	movetask = newtask(msec() + 250, movecanvas);
+
+	if (CurrentLayer != nil && newlayerimage(CurrentLayer))
+		sysfatal("newlayerimage: %r");
 }
 
 DefaultBinding DefaultBindings[] = 
 {
 	{BKeyboard, 'q', nil, BindingQuit},
+	{BKeyboard, 'c', nil, BindingClearLayer},
 	{BMouse, 1, nil, BindingStroke},
 	{BMouse, 8, nil, BindingZoomIn},
 	{BMouse, 16, nil, BindingZoomOut},
@@ -121,6 +137,7 @@
 	
 	b->type = type;
 	b->code = code;
+	b->state = BEleave;
 	if (BindingRoot != nil) {
 		for (e = BindingRoot; e->next != nil; e = e->next)
 			;
@@ -142,28 +159,28 @@
 
 	rc = 0;
 	for (b = BindingRoot; b != nil; b = b->next) {
+		e = BEleave;
 		if (b->type != type || b->code != code) {
-			if (b->type == type && b->state != BEleave && b->func != nil)
-				b->func(b->state = BEleave);				
-			continue;
+			if (b->state == BEleave)
+				continue;
+		} else {
+			switch (b->state) {
+				case BEenter:
+					e = BEin;
+					break;
+				case BEin:
+					e = BEin;
+					break;
+				case BEleave:
+					e = BEenter;
+					break;
+				default:
+					werrstr("invalid state");
+					break;
+			}
 		}
 		
-		e = BEleave;
-		switch (b->state) {
-			case BEenter:
-				e = BEin;
-				break;
-			case BEin:
-				e = BEin;
-				break;
-			case BEleave:
-				e = BEenter;
-				break;
-			default:
-				werrstr("invalid state");
-				break;
-		}
-		
+		b->state = e;
 		if (b->func != nil)
 			b->func(e);
 		if (b->command != nil)
--- a/dat.h
+++ b/dat.h
@@ -36,6 +36,7 @@
 // extern Rectangle CanvasSize = {0};
 // extern Point CanvasAt = {0};
 extern Layer * LayerRoot;
+extern Layer * CurrentLayer;
 extern Binding * BindingRoot;
 extern int RunLoop;
 extern int ZoomSensitivity;
--- a/fns.h
+++ b/fns.h
@@ -18,6 +18,8 @@
 int newtask(ulong, void (*)(void));
 int removetask(int);
 void runtasks(void);
+int newlayerimage(Layer *);
+Layer * newlayer(void);
 
 Point globaltoscreenpt(Point p);
 Point globaltoscreenatcanvaspt(Point p);
--- a/main.c
+++ b/main.c
@@ -47,8 +47,28 @@
 int ZoomTaskId = -1;
 int DrawOverlay = 0;
 
+int
+newlayerimage(Layer * l)
+{
+	if (l == nil) {
+		werrstr("l = nil");
+		return -1;
+	}
+
+	if (l->image != nil)
+		freeimage(l->image);
+
+	l->image = allocimage(display, CanvasSize, RGBA32, 1, DEFAULTLAYERCOLOR);
+	if (l->image == nil) {
+		werrstr("newlayer: %r");
+		return -1;
+	}
+	l->changed = 1;
+	return 0;
+}
+
 Layer *
-newlayer(ulong col)
+newlayer(void)
 {
 	Layer * l = nil, * e = nil;
 
@@ -59,9 +79,8 @@
 	if (l == nil)
 		sysfatal("newlayer: failed to allocate layer");
 	l->changed = 1;
-	l->image = allocimage(display, CanvasSize, RGBA32, 1, col);
-	if (l->image == nil)
-		sysfatal("newlayer: %r");
+	if (newlayerimage(l))
+		sysfatal("newlayerimage: %r");
 	if (RootLayer == nil) {
 		RootLayer = l;
 		CurrentLayer = l;
@@ -99,6 +118,7 @@
 		if (sr || l->changed || DrawAllLayers) {
 			draw(ViewImage, ViewImage->r, l->image, nil, ZP);
 			l->changed = 0;
+			sr = 1;
 		}
 
 	if (Background == nil)
@@ -116,9 +136,6 @@
 		draw(screen, RECTOPPT(ZoomedSize, screentoglobalatcanvaspt), ZoomedImage, nil, ZP);
 	}
 
-	if (OverlayImage != nil)
-		draw(screen, OverlayImage->r, OverlayImage, nil, ZP);
-
 	CanvasMoved = 0;
 	DrawAllLayers = 0;
 	DrawOverlay = 0;
@@ -419,21 +436,14 @@
 	setoverlaysize(screen->r);
 	CanvasSize = ZoomedSize = DEFAULTCANVASSIZE;
 	setcanvassize(DEFAULTCANVASSIZE);
-	newlayer(DEFAULTLAYERCOLOR);
+	newlayer();
 	applyzoom();
 	setdefaultbindings();
 
 	einit(Emouse | Ekeyboard);
+	etimer(0, UPDATEPERIOD);
 	drawcanvas();
 	for(;RunLoop;) {
-		d = msec();
-		if (d < LastUpdate)
-			LastUpdate = 0;
-		
-		d -= LastUpdate;
-	 	if (d < UPDATEPERIOD)
-	 		sleep(UPDATEPERIOD - d);
-		
 		runtasks();
 		switch (event(&e))
 		{
@@ -442,11 +452,22 @@
 			break;
 		case Emouse:
 			handlemouse(e.mouse);
-			break; 
+			break;
+		case 0:
+			break;
 		}
 
-		drawcanvas();
-		LastUpdate = msec();
+		d = msec();
+		if (d < LastUpdate)
+			LastUpdate = 0;
+
+		d -= LastUpdate;
+	 	if (d < UPDATEPERIOD)
+	 		sleep(1);
+		else {
+			drawcanvas();
+			LastUpdate = msec();
+		}
 	}
 
 	return;
--