shithub: riscv

Download patch

ref: acd1a3eddabf29ed08b5a0504b379141ab0e4acf
parent: a4d45256a728226267125da407ff6af36a717968
author: spew <devnull@localhost>
date: Fri Mar 10 04:57:23 EST 2017

games/galaxy: new mouse behavior
MB1 moves the galaxy. MB2 zooms the galaxy. New body creation
moved to the menu

--- a/sys/man/1/galaxy
+++ b/sys/man/1/galaxy
@@ -38,8 +38,14 @@
 universe.
 .SS Mouse commands
 .PP
-New planetary bodies can be created with mouse button 1.
-Holding button 1 will reposition the body.
+Holding mouse button 1 while dragging repositions the visible region of
+the galaxy. Holding mouse button 2 while dragging up or down zooms the
+visible region of the galaxy in or out, respectively.
+Mouse button 3 opens a menu with the following options:
+.TP
+.B "new body"
+Creates a new galactic body.
+Holding button 1 positions the body.
 Holding a button 1-2 chord changes the mass/size
 of the body. Holding a button 1-3 chord
 changes the initial velocity of the body. Releasing button 1
@@ -46,15 +52,6 @@
 restarts the simulator with the new body in motion. When new
 bodies are created, the simulator maintains the Galilean (inertial)
 reference frame where the center of mass of the galaxy is at rest.
-.PP
-Mouse button 2 repositions the visible region of the galaxy by dragging.
-.PP
-Mouse button 3 opens a menu with the following options:
-.TP
-.B zoom
-Prompts for a floating point value to change the scale of the
-simulation. E.g. a value of 2 will halve the scale (zoom in)
-and a value of 0.5 will double the scale (zoom out).
 .TP
 .B speed
 Prompts for a floating point value to change the speed of
--- a/sys/src/games/galaxy/galaxy.c
+++ b/sys/src/games/galaxy/galaxy.c
@@ -20,6 +20,18 @@
 	 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, }
 };
 
+Cursor zoomcursor = {
+	{-7, -7},
+	{0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
+	 0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
+	 0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8, },
+	{0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
+	 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
+	 0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
+	 0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00, }
+};
+
 Cursor pausecursor={
 	0, 0,
 	0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x07, 0xe0,
@@ -35,7 +47,7 @@
 
 enum {
 	STK = 8192,
-	ZOOM = 0,
+	DOBODY = 0,
 	SPEED,
 	GRAV,
 	SAVE,
@@ -56,12 +68,12 @@
 	LIM = 10,
 	dt²;
 char *file;
-int showv, showa, throttle;
+int showv, showa, throttle, paused;
 
 char *menustr[] = {
+	[DOBODY]	"new body",
 	[SAVE]	"save",
 	[LOAD]	"load",
-	[ZOOM]	"zoom",
 	[SPEED]	"speed",
 	[GRAV]	"gravity",
 	[EXIT]	"exit",
@@ -106,7 +118,7 @@
 void
 pause(int p, int id)
 {
-	static int paused, pid = -1;
+	static int pid = -1;
 
 	switch(p) {
 	default:
@@ -253,7 +265,15 @@
 	double f;
 	Body *b;
 
-	pause(0, 0);
+	for(;;) {
+		readmouse(mc);
+		if(mc->buttons == 0)
+			continue;
+		if(mc->buttons == 1)
+			break;
+		return;
+	}
+
 	b = body();
 	setpos(b);
 	setvel(b);
@@ -278,8 +298,6 @@
 	gc = center();
 	orig.x += gc.x / scale;
 	orig.y += gc.y / scale;
-
-	pause(1, 0);
 }
 
 char*
@@ -316,22 +334,58 @@
 	Point oldp, off;
 
 	setcursor(mc, &crosscursor);
-	pause(0, 0);
 	oldp = mc->xy;
 	for(;;) {
 		readmouse(mc);
-		if(mc->buttons != 2)
+		if(mc->buttons != 1)
 			break;
 		off = subpt(mc->xy, oldp);
 		oldp = mc->xy;
+		pause(0, 0);
 		orig = addpt(orig, off);
 		drawglxy();
+		pause(1, 0);
 	}
 	setcursor(mc, cursor);
-	pause(1, 0);
 }
 
 void
+dozoom(void)
+{
+	Point z, d;
+	double f, olds;
+
+	setcursor(mc, &zoomcursor);
+	for(;;) {
+		for(;;) {
+			readmouse(mc);
+			if(mc->buttons == 0)
+				continue;
+			if(mc->buttons != 2)
+				goto End;
+			break;
+		}
+		z = mc->xy;
+		olds = scale;
+		pause(0, 0);
+		for(;;) {
+			readmouse(mc);
+			if(mc->buttons != 2)
+				break;
+			drawglxy();
+			line(screen, z, (Point){z.x, mc->xy.y}, Enddisc, Enddisc, 0, display->white, ZP);
+			d = subpt(mc->xy, z);
+			f = tanh((double)d.y/200) + 1;
+			scale = f*olds;
+		}
+		pause(1, 0);
+	}
+
+End:
+	setcursor(mc, cursor);
+}
+
+void
 load(int fd)
 {
 	orig = divpt(subpt(screen->r.max, screen->r.min), 2);
@@ -349,6 +403,9 @@
 
 	pause(0, 0);
 	switch(menuhit(3, mc, &menu, nil)) {
+	case DOBODY:
+		dobody();
+		break;
 	case SAVE:
 		s = getinput("Enter file:", file);
 		if(s == nil || *s == '\0')
@@ -373,16 +430,6 @@
 		load(fd);
 		close(fd);
 		break;
-	case ZOOM:
-		s = getinput("Zoom multiplier:", nil);
-		if(s == nil || *s == '\0')
-			break;
-		z = strtod(s, nil);
-		free(s);
-		if(z <= 0)
-			break;
-		scale /= z;
-		break;
 	case SPEED:
 		s = getinput("Speed multiplier:", nil);
 		if(s == nil || *s == '\0')
@@ -420,10 +467,10 @@
 		readmouse(mc);
 		switch(mc->buttons) {
 		case 1:
-			dobody();
+			domove();
 			break;
 		case 2:
-			domove();
+			dozoom();
 			break;
 		case 4:
 			domenu();
@@ -451,7 +498,6 @@
 {
 	Keyboardctl *realkc;
 	Rune r;
-	static int paused;
 
 	threadsetname("keyboard");
 	realkc = initkeyboard(nil);
@@ -479,16 +525,16 @@
 			showa ^= 1;
 			break;
 		case ' ':
-			paused ^= 1;
 			if(paused) {
-				cursor = &pausecursor;
-				pause(0, 1);
-			} else {
 				cursor = nil;
 				pause(1, 1);
+			} else {
+				cursor = &pausecursor;
+				pause(0, 1);
 			}
 			setcursor(mc, cursor);
 		}
+		drawglxy();
 	}
 }