mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
puzzles: enhancements to mouse mode, zoom feature
- zoom now remembers position between activations (but not when exiting the plugin) - key repeat enabled when panning - moving mouse out of frame while zoomed will pan - mouse can be moved diagonally Change-Id: I39380ef7f36238700b6baa54cac036832933df67
This commit is contained in:
parent
385a917e20
commit
051eb3ea31
1 changed files with 94 additions and 65 deletions
|
|
@ -115,6 +115,7 @@ static inline void plot(fb_data *fb, int w, int h,
|
||||||
unsigned x, unsigned y, unsigned long a,
|
unsigned x, unsigned y, unsigned long a,
|
||||||
unsigned long r1, unsigned long g1, unsigned long b1,
|
unsigned long r1, unsigned long g1, unsigned long b1,
|
||||||
unsigned cl, unsigned cr, unsigned cu, unsigned cd);
|
unsigned cl, unsigned cr, unsigned cu, unsigned cd);
|
||||||
|
static void zoom_clamp_panning(void);
|
||||||
|
|
||||||
static midend *me = NULL;
|
static midend *me = NULL;
|
||||||
static unsigned *colors = NULL;
|
static unsigned *colors = NULL;
|
||||||
|
|
@ -137,7 +138,7 @@ static int mouse_x, mouse_y;
|
||||||
extern bool audiobuf_available; /* defined in rbmalloc.c */
|
extern bool audiobuf_available; /* defined in rbmalloc.c */
|
||||||
|
|
||||||
static fb_data *zoom_fb; /* dynamically allocated */
|
static fb_data *zoom_fb; /* dynamically allocated */
|
||||||
static int zoom_x, zoom_y, zoom_w, zoom_h, zoom_clipu, zoom_clipd, zoom_clipl, zoom_clipr;
|
static int zoom_x = -1, zoom_y = -1, zoom_w, zoom_h, zoom_clipu, zoom_clipd, zoom_clipl, zoom_clipr;
|
||||||
static int cur_font = FONT_UI;
|
static int cur_font = FONT_UI;
|
||||||
|
|
||||||
static bool need_draw_update = false;
|
static bool need_draw_update = false;
|
||||||
|
|
@ -1722,30 +1723,34 @@ static int process_input(int tmo, bool do_pausemenu)
|
||||||
* following code is needed for mouse mode. */
|
* following code is needed for mouse mode. */
|
||||||
if(mouse_mode)
|
if(mouse_mode)
|
||||||
{
|
{
|
||||||
static int last_mousedir = 0, held_count = 0, v = 1;
|
static int held_count = 0, v = 2;
|
||||||
|
|
||||||
|
int dx = 0, dy = 0;
|
||||||
|
|
||||||
if(button & BTN_UP)
|
if(button & BTN_UP)
|
||||||
state = CURSOR_UP;
|
dy -= 1;
|
||||||
else if(button & BTN_DOWN)
|
if(button & BTN_DOWN)
|
||||||
state = CURSOR_DOWN;
|
dy += 1;
|
||||||
else if(button & BTN_LEFT)
|
if(button & BTN_LEFT)
|
||||||
state = CURSOR_LEFT;
|
dx -= 1;
|
||||||
else if(button & BTN_RIGHT)
|
if(button & BTN_RIGHT)
|
||||||
state = CURSOR_RIGHT;
|
dx += 1;
|
||||||
|
|
||||||
unsigned released = ~button & last_keystate,
|
unsigned released = ~button & last_keystate,
|
||||||
pressed = button & ~last_keystate;
|
pressed = button & ~last_keystate;
|
||||||
|
|
||||||
last_keystate = button;
|
/* acceleration */
|
||||||
|
if(button && button == last_keystate)
|
||||||
/* move */
|
{
|
||||||
/* get the direction vector the cursor is moving in. */
|
if(++held_count % 4 == 0 && v < 15)
|
||||||
int new_x = mouse_x, new_y = mouse_y;
|
v++;
|
||||||
|
}
|
||||||
/* in src/misc.c */
|
else
|
||||||
move_cursor(state, &new_x, &new_y, LCD_WIDTH, LCD_HEIGHT, false);
|
{
|
||||||
|
LOGF("no buttons pressed, or state changed");
|
||||||
int dx = new_x - mouse_x, dy = new_y - mouse_y;
|
v = 1;
|
||||||
|
held_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
mouse_x += dx * v;
|
mouse_x += dx * v;
|
||||||
mouse_y += dy * v;
|
mouse_y += dy * v;
|
||||||
|
|
@ -1753,15 +1758,25 @@ static int process_input(int tmo, bool do_pausemenu)
|
||||||
/* clamp */
|
/* clamp */
|
||||||
/* The % operator with negative operands is messy; this is much
|
/* The % operator with negative operands is messy; this is much
|
||||||
* simpler. */
|
* simpler. */
|
||||||
|
bool clamped_x = false, clamped_y = false;
|
||||||
|
|
||||||
if(mouse_x < 0)
|
if(mouse_x < 0)
|
||||||
mouse_x = 0;
|
mouse_x = 0, clamped_x = true;
|
||||||
if(mouse_y < 0)
|
if(mouse_y < 0)
|
||||||
mouse_y = 0;
|
mouse_y = 0, clamped_y = true;
|
||||||
|
|
||||||
if(mouse_x >= LCD_WIDTH)
|
if(mouse_x >= LCD_WIDTH)
|
||||||
mouse_x = LCD_WIDTH - 1;
|
mouse_x = LCD_WIDTH - 1, clamped_x = true;
|
||||||
if(mouse_y >= LCD_HEIGHT)
|
if(mouse_y >= LCD_HEIGHT)
|
||||||
mouse_y = LCD_HEIGHT - 1;
|
mouse_y = LCD_HEIGHT - 1, clamped_y = true;
|
||||||
|
|
||||||
|
if((clamped_x || clamped_y) && zoom_enabled) {
|
||||||
|
if(clamped_x)
|
||||||
|
zoom_x += dx * v;
|
||||||
|
if(clamped_y)
|
||||||
|
zoom_y += dy * v;
|
||||||
|
zoom_clamp_panning();
|
||||||
|
}
|
||||||
|
|
||||||
/* clicking/dragging */
|
/* clicking/dragging */
|
||||||
/* rclick on hold requires that we fire left-click on a
|
/* rclick on hold requires that we fire left-click on a
|
||||||
|
|
@ -1777,32 +1792,24 @@ static int process_input(int tmo, bool do_pausemenu)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(pressed & BTN_FIRE)
|
if(pressed & BTN_FIRE) {
|
||||||
send_click(LEFT_BUTTON, false);
|
send_click(LEFT_BUTTON, false);
|
||||||
|
accept_input = false;
|
||||||
|
}
|
||||||
else if(released & BTN_FIRE)
|
else if(released & BTN_FIRE)
|
||||||
send_click(LEFT_RELEASE, false);
|
send_click(LEFT_RELEASE, false);
|
||||||
else if(button & BTN_FIRE)
|
else if(button & BTN_FIRE)
|
||||||
send_click(LEFT_DRAG, false);
|
send_click(LEFT_DRAG, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* acceleration */
|
if(!button)
|
||||||
if(state && state == last_mousedir)
|
|
||||||
{
|
{
|
||||||
if(++held_count % 5 == 0 && v < 15)
|
LOGF("all keys released, accepting further input");
|
||||||
v++;
|
accept_input = true;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!button)
|
|
||||||
{
|
|
||||||
LOGF("all keys released, accepting further input");
|
|
||||||
accept_input = true;
|
|
||||||
}
|
|
||||||
last_mousedir = state;
|
|
||||||
v = 1;
|
|
||||||
held_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_keystate = button;
|
||||||
|
|
||||||
/* no buttons are sent to the midend in mouse mode */
|
/* no buttons are sent to the midend in mouse mode */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1972,6 +1979,18 @@ static int process_input(int tmo, bool do_pausemenu)
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void zoom_clamp_panning(void) {
|
||||||
|
if(zoom_y < 0)
|
||||||
|
zoom_y = 0;
|
||||||
|
if(zoom_x < 0)
|
||||||
|
zoom_x = 0;
|
||||||
|
|
||||||
|
if(zoom_y + LCD_HEIGHT >= zoom_h)
|
||||||
|
zoom_y = zoom_h - LCD_HEIGHT;
|
||||||
|
if(zoom_x + LCD_WIDTH >= zoom_w)
|
||||||
|
zoom_x = zoom_w - LCD_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function handles zoom mode, where the user can either pan
|
/* This function handles zoom mode, where the user can either pan
|
||||||
* around a zoomed-in image or play a zoomed-in version of the game. */
|
* around a zoomed-in image or play a zoomed-in version of the game. */
|
||||||
static void zoom(void)
|
static void zoom(void)
|
||||||
|
|
@ -2001,13 +2020,21 @@ static void zoom(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set position */
|
||||||
|
|
||||||
|
if(zoom_x < 0) {
|
||||||
|
/* first run */
|
||||||
|
zoom_x = zoom_w / 2 - LCD_WIDTH / 2;
|
||||||
|
zoom_y = zoom_h / 2 - LCD_HEIGHT / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zoom_clamp_panning();
|
||||||
|
|
||||||
zoom_enabled = true;
|
zoom_enabled = true;
|
||||||
|
|
||||||
/* draws go to the zoom framebuffer */
|
/* draws go to the zoom framebuffer */
|
||||||
midend_force_redraw(me);
|
midend_force_redraw(me);
|
||||||
|
|
||||||
zoom_x = zoom_y = 0;
|
|
||||||
|
|
||||||
rb->lcd_bitmap_part(zoom_fb, zoom_x, zoom_y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h),
|
rb->lcd_bitmap_part(zoom_fb, zoom_x, zoom_y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h),
|
||||||
0, 0, LCD_WIDTH, LCD_HEIGHT);
|
0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||||
|
|
||||||
|
|
@ -2031,18 +2058,25 @@ static void zoom(void)
|
||||||
if(view_mode)
|
if(view_mode)
|
||||||
{
|
{
|
||||||
int button = rb->button_get_w_tmo(timer_on ? TIMER_INTERVAL : -1);
|
int button = rb->button_get_w_tmo(timer_on ? TIMER_INTERVAL : -1);
|
||||||
|
|
||||||
|
exit_on_usb(button);
|
||||||
|
|
||||||
switch(button)
|
switch(button)
|
||||||
{
|
{
|
||||||
case BTN_UP:
|
case BTN_UP:
|
||||||
|
case BTN_UP | BUTTON_REPEAT:
|
||||||
zoom_y -= PAN_Y; /* clamped later */
|
zoom_y -= PAN_Y; /* clamped later */
|
||||||
break;
|
break;
|
||||||
case BTN_DOWN:
|
case BTN_DOWN:
|
||||||
|
case BTN_DOWN | BUTTON_REPEAT:
|
||||||
zoom_y += PAN_Y; /* clamped later */
|
zoom_y += PAN_Y; /* clamped later */
|
||||||
break;
|
break;
|
||||||
case BTN_LEFT:
|
case BTN_LEFT:
|
||||||
|
case BTN_LEFT | BUTTON_REPEAT:
|
||||||
zoom_x -= PAN_X; /* clamped later */
|
zoom_x -= PAN_X; /* clamped later */
|
||||||
break;
|
break;
|
||||||
case BTN_RIGHT:
|
case BTN_RIGHT:
|
||||||
|
case BTN_RIGHT | BUTTON_REPEAT:
|
||||||
zoom_x += PAN_X; /* clamped later */
|
zoom_x += PAN_X; /* clamped later */
|
||||||
break;
|
break;
|
||||||
case BTN_PAUSE:
|
case BTN_PAUSE:
|
||||||
|
|
@ -2050,22 +2084,15 @@ static void zoom(void)
|
||||||
sfree(zoom_fb);
|
sfree(zoom_fb);
|
||||||
fix_size();
|
fix_size();
|
||||||
return;
|
return;
|
||||||
case BTN_FIRE:
|
case BTN_FIRE | BUTTON_REL:
|
||||||
|
/* state change to interaction mode */
|
||||||
view_mode = false;
|
view_mode = false;
|
||||||
continue;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(zoom_y < 0)
|
zoom_clamp_panning();
|
||||||
zoom_y = 0;
|
|
||||||
if(zoom_x < 0)
|
|
||||||
zoom_x = 0;
|
|
||||||
|
|
||||||
if(zoom_y + LCD_HEIGHT >= zoom_h)
|
|
||||||
zoom_y = zoom_h - LCD_HEIGHT;
|
|
||||||
if(zoom_x + LCD_WIDTH >= zoom_w)
|
|
||||||
zoom_x = zoom_w - LCD_WIDTH;
|
|
||||||
|
|
||||||
if(timer_on)
|
if(timer_on)
|
||||||
timer_cb();
|
timer_cb();
|
||||||
|
|
@ -2081,9 +2108,23 @@ static void zoom(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* The cursor is always in screenspace coordinates; when
|
||||||
|
* zoomed, this means the mouse is always restricted to
|
||||||
|
* the bounds of the physical display, not the virtual
|
||||||
|
* zoom framebuffer. */
|
||||||
|
if(mouse_mode)
|
||||||
|
draw_mouse();
|
||||||
|
|
||||||
|
rb->lcd_update();
|
||||||
|
|
||||||
|
if(mouse_mode)
|
||||||
|
clear_mouse();
|
||||||
|
|
||||||
/* basically a copy-pasta'd main loop */
|
/* basically a copy-pasta'd main loop */
|
||||||
int button = process_input(timer_on ? TIMER_INTERVAL : -1, false);
|
int button = process_input(timer_on ? TIMER_INTERVAL : -1, false);
|
||||||
|
|
||||||
|
exit_on_usb(button);
|
||||||
|
|
||||||
if(button < 0)
|
if(button < 0)
|
||||||
{
|
{
|
||||||
view_mode = true;
|
view_mode = true;
|
||||||
|
|
@ -2104,18 +2145,6 @@ static void zoom(void)
|
||||||
|
|
||||||
draw_title(false);
|
draw_title(false);
|
||||||
|
|
||||||
/* The cursor is always in screenspace coordinates; when
|
|
||||||
* zoomed, this means the mouse is always restricted to
|
|
||||||
* the bounds of the physical display, not the virtual
|
|
||||||
* zoom framebuffer. */
|
|
||||||
if(mouse_mode)
|
|
||||||
draw_mouse();
|
|
||||||
|
|
||||||
rb->lcd_update();
|
|
||||||
|
|
||||||
if(mouse_mode)
|
|
||||||
clear_mouse();
|
|
||||||
|
|
||||||
rb->yield();
|
rb->yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue