ref: 8cac775c460cd32ffa82a756e6c7e6dc6d7fda51
parent: c7d5348ddbb3bdb6358c153795bb4c0e18af1375
author: qwx <qwx@sciops.net>
date: Wed Nov 30 00:52:00 EST 2022
add zooming into a range
--- a/dat.h
+++ b/dat.h
@@ -28,7 +28,6 @@
extern usize totalsz;
extern int stereo;
-extern int zoom;
extern int debug;
#define MIN(x,y) ((x) < (y) ? (x) : (y))
--- a/draw.c
+++ b/draw.c
@@ -26,6 +26,7 @@
static uchar *sbuf;
static usize sbufsz;
static int sampwidth = 1;
+static double zoom = 1.0;
static Image *
eallocimage(Rectangle r, int repl, ulong col)
@@ -220,22 +221,46 @@
}
void
-setzoom(int Δz, int pow)
+setzoom(int Δz, int mul)
{
- int z;
+ double z;
- if(!pow)
+ if(!mul)
z = zoom + Δz;
else if(Δz < 0)
- z = zoom >> -Δz;
+ z = zoom / pow(2, -Δz);
else
- z = zoom << Δz;
- if(z < 1 || z > (totalsz / 4) / Dx(screen->r))
+ z = zoom * pow(2, Δz);
+ if(z < 1.0 || z > (totalsz / Sampsz) / Dx(screen->r))
return;
zoom = z;
redraw(0);
}
+int
+zoominto(vlong from, vlong to)
+{
+ if(dot.from.pos == 0 && dot.to.pos == totalsz){
+ fprint(2, "not a range\n");
+ return -1;
+ }
+ if(from < 0)
+ from = 0;
+ from &= ~3;
+ if(to >= totalsz)
+ to = totalsz;
+ to &= ~3;
+ if((to - from) / Sampsz < Dx(screen->r)){
+ werrstr("range too small");
+ return -1;
+ }
+ views = from;
+ viewe = to;
+ zoom = (double)totalsz / (to - from);
+ redraw(0);
+ return 0;
+}
+
void
setpan(int Δx)
{
@@ -326,7 +351,7 @@
usize span;
lockdisplay(display);
- T = totalsz / zoom / Dx(screen->r) & ~3;
+ T = (vlong)(totalsz / zoom / Dx(screen->r)) & ~3;
if(T == 0)
T = 4;
span = Dx(screen->r) * T;
--- a/fns.h
+++ b/fns.h
@@ -2,6 +2,7 @@
void initcmd(void);
void update(void);
void setzoom(int, int);
+int zoominto(vlong, vlong);
void setpan(int);
void setloop(vlong);
void setofs(usize);
--- a/pplay.c
+++ b/pplay.c
@@ -9,7 +9,7 @@
extern QLock lsync;
-int stereo, zoom = 1;
+int stereo;
int debug;
static Keyboardctl *kc;
@@ -140,12 +140,13 @@
break;
case 2:
switch(r){
+ case Kdel:
+ case 'q': threadexitsall(nil);
case ' ': toggleplay(); break;
case 'b': setjump(dot.from.pos); break;
case Kesc: setrange(0, totalsz); update(); break;
- case Kdel:
- case 'q': threadexitsall(nil);
- case 'z': setzoom(-zoom + 1, 0); break;
+ case '\n': zoominto(dot.from.pos, dot.to.pos); break;
+ case 'z': zoominto(0, totalsz); break;
case '-': setzoom(-1, 0); break;
case '=': setzoom(1, 0); break;
case '_': setzoom(-1, 1); break;