games/galaxy: new mouse behavior

MB1 moves the galaxy. MB2 zooms the galaxy. New body creation
moved to the menu
This commit is contained in:
spew 2017-03-10 09:57:23 -06:00
parent a4d45256a7
commit acd1a3edda
2 changed files with 81 additions and 38 deletions

View file

@ -38,23 +38,20 @@ option. If no file is read then the simulator starts with an empty
universe. universe.
.SS Mouse commands .SS Mouse commands
.PP .PP
New planetary bodies can be created with mouse button 1. Holding mouse button 1 while dragging repositions the visible region of
Holding button 1 will reposition the body. 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 Holding a button 1-2 chord changes the mass/size
of the body. Holding a button 1-3 chord of the body. Holding a button 1-3 chord
changes the initial velocity of the body. Releasing button 1 changes the initial velocity of the body. Releasing button 1
restarts the simulator with the new body in motion. When new restarts the simulator with the new body in motion. When new
bodies are created, the simulator maintains the Galilean (inertial) bodies are created, the simulator maintains the Galilean (inertial)
reference frame where the center of mass of the galaxy is at rest. 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 .TP
.B speed .B speed
Prompts for a floating point value to change the speed of Prompts for a floating point value to change the speed of

View file

@ -20,6 +20,18 @@ Cursor crosscursor = {
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, } 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={ Cursor pausecursor={
0, 0, 0, 0,
0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x07, 0xe0, 0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x07, 0xe0,
@ -35,7 +47,7 @@ Cursor pausecursor={
enum { enum {
STK = 8192, STK = 8192,
ZOOM = 0, DOBODY = 0,
SPEED, SPEED,
GRAV, GRAV,
SAVE, SAVE,
@ -56,12 +68,12 @@ double
LIM = 10, LIM = 10,
dt²; dt²;
char *file; char *file;
int showv, showa, throttle; int showv, showa, throttle, paused;
char *menustr[] = { char *menustr[] = {
[DOBODY] "new body",
[SAVE] "save", [SAVE] "save",
[LOAD] "load", [LOAD] "load",
[ZOOM] "zoom",
[SPEED] "speed", [SPEED] "speed",
[GRAV] "gravity", [GRAV] "gravity",
[EXIT] "exit", [EXIT] "exit",
@ -106,7 +118,7 @@ randcol(void)
void void
pause(int p, int id) pause(int p, int id)
{ {
static int paused, pid = -1; static int pid = -1;
switch(p) { switch(p) {
default: default:
@ -253,7 +265,15 @@ dobody(void)
double f; double f;
Body *b; Body *b;
pause(0, 0); for(;;) {
readmouse(mc);
if(mc->buttons == 0)
continue;
if(mc->buttons == 1)
break;
return;
}
b = body(); b = body();
setpos(b); setpos(b);
setvel(b); setvel(b);
@ -278,8 +298,6 @@ dobody(void)
gc = center(); gc = center();
orig.x += gc.x / scale; orig.x += gc.x / scale;
orig.y += gc.y / scale; orig.y += gc.y / scale;
pause(1, 0);
} }
char* char*
@ -316,19 +334,55 @@ domove(void)
Point oldp, off; Point oldp, off;
setcursor(mc, &crosscursor); setcursor(mc, &crosscursor);
pause(0, 0);
oldp = mc->xy; oldp = mc->xy;
for(;;) {
readmouse(mc);
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);
}
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(;;) { for(;;) {
readmouse(mc); readmouse(mc);
if(mc->buttons != 2) if(mc->buttons != 2)
break; break;
off = subpt(mc->xy, oldp);
oldp = mc->xy;
orig = addpt(orig, off);
drawglxy(); 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;
} }
setcursor(mc, cursor);
pause(1, 0); pause(1, 0);
}
End:
setcursor(mc, cursor);
} }
void void
@ -349,6 +403,9 @@ domenu(void)
pause(0, 0); pause(0, 0);
switch(menuhit(3, mc, &menu, nil)) { switch(menuhit(3, mc, &menu, nil)) {
case DOBODY:
dobody();
break;
case SAVE: case SAVE:
s = getinput("Enter file:", file); s = getinput("Enter file:", file);
if(s == nil || *s == '\0') if(s == nil || *s == '\0')
@ -373,16 +430,6 @@ domenu(void)
load(fd); load(fd);
close(fd); close(fd);
break; 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: case SPEED:
s = getinput("Speed multiplier:", nil); s = getinput("Speed multiplier:", nil);
if(s == nil || *s == '\0') if(s == nil || *s == '\0')
@ -420,10 +467,10 @@ mousethread(void*)
readmouse(mc); readmouse(mc);
switch(mc->buttons) { switch(mc->buttons) {
case 1: case 1:
dobody(); domove();
break; break;
case 2: case 2:
domove(); dozoom();
break; break;
case 4: case 4:
domenu(); domenu();
@ -451,7 +498,6 @@ kbdthread(void*)
{ {
Keyboardctl *realkc; Keyboardctl *realkc;
Rune r; Rune r;
static int paused;
threadsetname("keyboard"); threadsetname("keyboard");
realkc = initkeyboard(nil); realkc = initkeyboard(nil);
@ -479,16 +525,16 @@ kbdthread(void*)
showa ^= 1; showa ^= 1;
break; break;
case ' ': case ' ':
paused ^= 1;
if(paused) { if(paused) {
cursor = &pausecursor;
pause(0, 1);
} else {
cursor = nil; cursor = nil;
pause(1, 1); pause(1, 1);
} else {
cursor = &pausecursor;
pause(0, 1);
} }
setcursor(mc, cursor); setcursor(mc, cursor);
} }
drawglxy();
} }
} }