shithub: riscv

Download patch

ref: dff1e3813fb0deb18ca790b7c28f6a1405720ff6
parent: ffa430c57068e65f5247f22a862a78ed11f9da18
author: spew <devnull@localhost>
date: Sun Mar 12 14:24:45 EDT 2017

games/galaxy: fix zoom

Zooming when far away from the center of gravity
of the galaxy would zoom the center of the screen
out of view. Now adjust the origin so that the
center of the screen stays centered

--- a/sys/src/games/galaxy/body.c
+++ b/sys/src/games/galaxy/body.c
@@ -31,6 +31,16 @@
 	return b;
 }
 
+Point
+topoint(Vector v)
+{
+	Point p;
+
+	p.x = v.x/scale + orig.x;
+	p.y = v.y/scale + orig.y;
+	return p;
+}
+
 void
 drawbody(Body *b)
 {
@@ -37,8 +47,7 @@
 	Point pos, v;
 	int s;
 
-	pos.x = b->x / scale + orig.x;
-	pos.y = b->y / scale + orig.y;
+	pos = topoint(b->Vector);
 	s = b->size/scale;
 	fillellipse(screen, pos, s, s, b->col, ZP);
 	v.x = b->v.x/scale*10;
--- a/sys/src/games/galaxy/galaxy.c
+++ b/sys/src/games/galaxy/galaxy.c
@@ -171,8 +171,7 @@
 
 	draw(screen, screen->r, display->black, 0, ZP);
 	for(b = glxy.a; b < glxy.a + glxy.l; b++) {
-		pos.x = b->x / scale + orig.x;
-		pos.y = b->y / scale + orig.y;
+		pos = topoint(b->Vector);
 		s = b->size/scale;
 		fillellipse(screen, pos, s, s, b->col, ZP);
 		if(showv) {
@@ -198,8 +197,7 @@
 	Point pos, d;
 	double h;
 
-	pos.x = b->x / scale + orig.x;
-	pos.y = b->y / scale + orig.y;
+	pos = topoint(b->Vector);
 	d = subpt(mc->xy, pos);
 	h = hypot(d.x, d.y);
 	b->size = h == 0 ? scale : h*scale;
@@ -211,21 +209,13 @@
 {
 	Point pos, d;
 
-	pos.x = b->x / scale + orig.x;
-	pos.y = b->y / scale + orig.y;
+	pos = topoint(b->Vector);
 	d = subpt(mc->xy, pos);
-	b->v.x = (double)d.x*scale/10;
-	b->v.y = (double)d.y*scale/10;
+	b->v.x = d.x*scale/10;
+	b->v.y = d.y*scale/10;
 }
 
 void
-setpos(Body *b)
-{
-	b->x = (mc->xy.x - orig.x) * scale;
-	b->y = (mc->xy.y - orig.y) * scale;
-}
-
-void
 dosize(Body *b)
 {
 	Point p;
@@ -275,7 +265,6 @@
 	}
 
 	b = body();
-	setpos(b);
 	setvel(b);
 	setsize(b);
 	b->col = randcol();
@@ -290,7 +279,7 @@
 		else if(mc->buttons == 5)
 			dovel(b);
 		else
-			setpos(b);
+			b->Vector = tovector(mc->xy);
 	}
 
 	CHECKLIM(b, f);
@@ -349,30 +338,41 @@
 	setcursor(mc, cursor);
 }
 
+Point
+screencenter(void)
+{
+	Point sc;
+
+	sc = divpt(subpt(screen->r.max, screen->r.min), 2);
+	return addpt(screen->r.min, sc);
+}
+
 void
 dozoom(void)
 {
-	Point z, d;
-	double f, olds;
+	Point oxy, d, sc, off;
+	Vector gsc;
+	double z, oscale;
 
 	setcursor(mc, &zoomcursor);
-
-	z = mc->xy;
-	olds = scale;
+	oxy = mc->xy;
+	oscale = scale;
 	for(;;) {
 		readmouse(mc);
 		if(mc->buttons != 2)
 			break;
-		d = subpt(mc->xy, z);
-		f = tanh((double)d.y/200) + 1;
+		d = subpt(mc->xy, oxy);
+		z = tanh((double)d.y/200) + 1;
+		sc = screencenter();
+		gsc = tovector(sc);
 		pause(0, 0);
-		scale = f*olds;
+		scale = z*oscale;
+		off = subpt(topoint(gsc), sc);
+		orig = subpt(orig, off);
 		drawglxy();
 		pause(1, 0);
 	}
-
 	setcursor(mc, cursor);
-	pause(1, 0);
 }
 
 void
@@ -579,6 +579,16 @@
 	}
 }
 
+Vector
+tovector(Point p)
+{
+	Vector v;
+
+	v.x = (p.x-orig.x) * scale;
+	v.y = (p.y-orig.y) * scale;
+	return v;
+}
+
 void
 usage(void)
 {
@@ -632,8 +642,7 @@
 		sysfatal("initmouse failed: %r");
 
 	dt² = dt*dt;
-	orig = divpt(subpt(screen->r.max, screen->r.min), 2);
-	orig = addpt(orig, screen->r.min);
+	orig = screencenter();
 	glxyinit();
 	quadsinit();
 	if(doload)
--- a/sys/src/games/galaxy/galaxy.h
+++ b/sys/src/games/galaxy/galaxy.h
@@ -55,14 +55,16 @@
 QB space;
 
 Image *randcol(void);
+Point topoint(Vector);
+Vector tovector(Point);
 
 Body *body(void);
 void drawbody(Body*);
 Vector center(void);
 void glxyinit(void);
+int Bfmt(Fmt*);
 void readglxy(int);
 void writeglxy(int);
-int Bfmt(Fmt*);
 
 void quadcalc(Body*, QB, double);
 int quadins(Body*, double);