+ } else if (IS_CURSOR_MOVE(button)) {
+ if (!ui->cur_jumping) {
+ /* Not jumping; move cursor as usual, making sure we don't
+ * leave the gameboard (which may be an irregular shape) */
+ int cx = ui->cur_x, cy = ui->cur_y;
+ move_cursor(button, &cx, &cy, w, h, 0);
+ ui->cur_visible = 1;
+ if (state->grid[cy*w+cx] == GRID_HOLE ||
+ state->grid[cy*w+cx] == GRID_PEG) {
+ ui->cur_x = cx;
+ ui->cur_y = cy;
+ }
+ return "";
+ } else {
+ int dx, dy, mx, my, jx, jy;
+
+ /* We're jumping; if the requested direction has a hole, and
+ * there's a peg in the way, */
+ assert(state->grid[ui->cur_y*w+ui->cur_x] == GRID_PEG);
+ dx = (button == CURSOR_RIGHT) ? 1 : (button == CURSOR_LEFT) ? -1 : 0;
+ dy = (button == CURSOR_DOWN) ? 1 : (button == CURSOR_UP) ? -1 : 0;
+
+ mx = ui->cur_x+dx; my = ui->cur_y+dy;
+ jx = mx+dx; jy = my+dy;
+
+ ui->cur_jumping = 0; /* reset, whatever. */
+ if (jx >= 0 && jy >= 0 && jx < w && jy < h &&
+ state->grid[my*w+mx] == GRID_PEG &&
+ state->grid[jy*w+jx] == GRID_HOLE) {
+ /* Move cursor to the jumped-to location (this felt more
+ * natural while playtesting) */
+ sprintf(buf, "%d,%d-%d,%d", ui->cur_x, ui->cur_y, jx, jy);
+ ui->cur_x = jx; ui->cur_y = jy;
+ return dupstr(buf);
+ }
+ return "";
+ }
+ } else if (IS_CURSOR_SELECT(button)) {
+ if (!ui->cur_visible) {
+ ui->cur_visible = 1;
+ return "";
+ }
+ if (ui->cur_jumping) {
+ ui->cur_jumping = 0;
+ return "";
+ }
+ if (state->grid[ui->cur_y*w+ui->cur_x] == GRID_PEG) {
+ /* cursor is on peg: next arrow-move wil jump. */
+ ui->cur_jumping = 1;
+ return "";
+ }
+ return NULL;