diff --git a/ubb-la/README b/ubb-la/README index aa939b7..0571b0f 100644 --- a/ubb-la/README +++ b/ubb-la/README @@ -82,7 +82,8 @@ command line. Example: In the GUI, the following keys are available: - Left/Right Pan the waveform left/right + Left/Right Pan the waveform left/right. With Shift, jump to the + next change on any channel in the specified direction. Up/Down Zoom in/out Space Set the user origin (upward-facing green triangle) at the current position and display the time to diff --git a/ubb-la/gui.c b/ubb-la/gui.c index dd619be..8cf28ab 100644 --- a/ubb-la/gui.c +++ b/ubb-la/gui.c @@ -485,13 +485,36 @@ static int pos_step(int zoom) } +static int smart_pos(const uint8_t *buf, int skip, int nibbles, + int pos, int dir) +{ + uint8_t ref; + + if (dir < 0) { + if (!pos) + return pos; + ref = get_sample(buf, skip+pos-1); + } else { + ref = get_sample(buf, skip+pos); + } + do { + pos += dir; + if (pos < 0 || pos == nibbles-skip) + return pos-dir; + } while (get_sample(buf, skip+pos) == ref); + if (dir < 0) + pos++; + return pos; +} + + void gui(const uint8_t *buf, int skip, int nibbles, double freq) { SDL_Event event; int pos = (skip+nibbles) >> 1; int zoom; /* < 0: zoom out; 0: 1 pixel = 1 sample; > 1: zoom in */ int min_zoom = 0; - int i; + int i, shift; while (XWIDTH < (nibbles-skip) >> -min_zoom) min_zoom--; @@ -515,6 +538,7 @@ void gui(const uint8_t *buf, int skip, int nibbles, double freq) SDL_WaitEvent(&event); switch (event.type) { case SDL_KEYDOWN: + shift = event.key.keysym.mod & KMOD_SHIFT; switch (event.key.keysym.sym) { case SDLK_UP: if (zoom < MAX_ZOOM) @@ -525,14 +549,24 @@ void gui(const uint8_t *buf, int skip, int nibbles, double freq) zoom--; break; case SDLK_LEFT: - pos -= pos_step(zoom); - if (pos < 0) - pos = 0; + if (shift) { + pos = smart_pos(buf, + skip, nibbles, pos, -1); + } else { + pos -= pos_step(zoom); + if (pos < 0) + pos = 0; + } break; case SDLK_RIGHT: - pos += pos_step(zoom); - if (pos > nibbles-skip-1) - pos = nibbles-skip-1; + if (shift) { + pos = smart_pos(buf, + skip, nibbles, pos, 1); + } else { + pos += pos_step(zoom); + if (pos > nibbles-skip-1) + pos = nibbles-skip-1; + } break; case SDLK_SPACE: if (pos == user_ref) @@ -543,6 +577,9 @@ void gui(const uint8_t *buf, int skip, int nibbles, double freq) case SDLK_RETURN: case SDLK_q: return; + case SDLK_LSHIFT: + case SDLK_RSHIFT: + continue; default: printf("%x\n", event.key.keysym.sym); continue;