diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/puzzles/rockbox.c | 159 |
1 files changed, 94 insertions, 65 deletions
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c index 7fe7998c39..04d7e6d6e4 100644 --- a/apps/plugins/puzzles/rockbox.c +++ b/apps/plugins/puzzles/rockbox.c | |||
@@ -115,6 +115,7 @@ static inline void plot(fb_data *fb, int w, int h, | |||
115 | unsigned x, unsigned y, unsigned long a, | 115 | unsigned x, unsigned y, unsigned long a, |
116 | unsigned long r1, unsigned long g1, unsigned long b1, | 116 | unsigned long r1, unsigned long g1, unsigned long b1, |
117 | unsigned cl, unsigned cr, unsigned cu, unsigned cd); | 117 | unsigned cl, unsigned cr, unsigned cu, unsigned cd); |
118 | static void zoom_clamp_panning(void); | ||
118 | 119 | ||
119 | static midend *me = NULL; | 120 | static midend *me = NULL; |
120 | static unsigned *colors = NULL; | 121 | static unsigned *colors = NULL; |
@@ -137,7 +138,7 @@ static int mouse_x, mouse_y; | |||
137 | extern bool audiobuf_available; /* defined in rbmalloc.c */ | 138 | extern bool audiobuf_available; /* defined in rbmalloc.c */ |
138 | 139 | ||
139 | static fb_data *zoom_fb; /* dynamically allocated */ | 140 | static fb_data *zoom_fb; /* dynamically allocated */ |
140 | static int zoom_x, zoom_y, zoom_w, zoom_h, zoom_clipu, zoom_clipd, zoom_clipl, zoom_clipr; | 141 | static int zoom_x = -1, zoom_y = -1, zoom_w, zoom_h, zoom_clipu, zoom_clipd, zoom_clipl, zoom_clipr; |
141 | static int cur_font = FONT_UI; | 142 | static int cur_font = FONT_UI; |
142 | 143 | ||
143 | static bool need_draw_update = false; | 144 | static bool need_draw_update = false; |
@@ -1722,30 +1723,34 @@ static int process_input(int tmo, bool do_pausemenu) | |||
1722 | * following code is needed for mouse mode. */ | 1723 | * following code is needed for mouse mode. */ |
1723 | if(mouse_mode) | 1724 | if(mouse_mode) |
1724 | { | 1725 | { |
1725 | static int last_mousedir = 0, held_count = 0, v = 1; | 1726 | static int held_count = 0, v = 2; |
1727 | |||
1728 | int dx = 0, dy = 0; | ||
1726 | 1729 | ||
1727 | if(button & BTN_UP) | 1730 | if(button & BTN_UP) |
1728 | state = CURSOR_UP; | 1731 | dy -= 1; |
1729 | else if(button & BTN_DOWN) | 1732 | if(button & BTN_DOWN) |
1730 | state = CURSOR_DOWN; | 1733 | dy += 1; |
1731 | else if(button & BTN_LEFT) | 1734 | if(button & BTN_LEFT) |
1732 | state = CURSOR_LEFT; | 1735 | dx -= 1; |
1733 | else if(button & BTN_RIGHT) | 1736 | if(button & BTN_RIGHT) |
1734 | state = CURSOR_RIGHT; | 1737 | dx += 1; |
1735 | 1738 | ||
1736 | unsigned released = ~button & last_keystate, | 1739 | unsigned released = ~button & last_keystate, |
1737 | pressed = button & ~last_keystate; | 1740 | pressed = button & ~last_keystate; |
1738 | |||
1739 | last_keystate = button; | ||
1740 | |||
1741 | /* move */ | ||
1742 | /* get the direction vector the cursor is moving in. */ | ||
1743 | int new_x = mouse_x, new_y = mouse_y; | ||
1744 | |||
1745 | /* in src/misc.c */ | ||
1746 | move_cursor(state, &new_x, &new_y, LCD_WIDTH, LCD_HEIGHT, false); | ||
1747 | 1741 | ||
1748 | int dx = new_x - mouse_x, dy = new_y - mouse_y; | 1742 | /* acceleration */ |
1743 | if(button && button == last_keystate) | ||
1744 | { | ||
1745 | if(++held_count % 4 == 0 && v < 15) | ||
1746 | v++; | ||
1747 | } | ||
1748 | else | ||
1749 | { | ||
1750 | LOGF("no buttons pressed, or state changed"); | ||
1751 | v = 1; | ||
1752 | held_count = 0; | ||
1753 | } | ||
1749 | 1754 | ||
1750 | mouse_x += dx * v; | 1755 | mouse_x += dx * v; |
1751 | mouse_y += dy * v; | 1756 | mouse_y += dy * v; |
@@ -1753,15 +1758,25 @@ static int process_input(int tmo, bool do_pausemenu) | |||
1753 | /* clamp */ | 1758 | /* clamp */ |
1754 | /* The % operator with negative operands is messy; this is much | 1759 | /* The % operator with negative operands is messy; this is much |
1755 | * simpler. */ | 1760 | * simpler. */ |
1761 | bool clamped_x = false, clamped_y = false; | ||
1762 | |||
1756 | if(mouse_x < 0) | 1763 | if(mouse_x < 0) |
1757 | mouse_x = 0; | 1764 | mouse_x = 0, clamped_x = true; |
1758 | if(mouse_y < 0) | 1765 | if(mouse_y < 0) |
1759 | mouse_y = 0; | 1766 | mouse_y = 0, clamped_y = true; |
1760 | 1767 | ||
1761 | if(mouse_x >= LCD_WIDTH) | 1768 | if(mouse_x >= LCD_WIDTH) |
1762 | mouse_x = LCD_WIDTH - 1; | 1769 | mouse_x = LCD_WIDTH - 1, clamped_x = true; |
1763 | if(mouse_y >= LCD_HEIGHT) | 1770 | if(mouse_y >= LCD_HEIGHT) |
1764 | mouse_y = LCD_HEIGHT - 1; | 1771 | mouse_y = LCD_HEIGHT - 1, clamped_y = true; |
1772 | |||
1773 | if((clamped_x || clamped_y) && zoom_enabled) { | ||
1774 | if(clamped_x) | ||
1775 | zoom_x += dx * v; | ||
1776 | if(clamped_y) | ||
1777 | zoom_y += dy * v; | ||
1778 | zoom_clamp_panning(); | ||
1779 | } | ||
1765 | 1780 | ||
1766 | /* clicking/dragging */ | 1781 | /* clicking/dragging */ |
1767 | /* rclick on hold requires that we fire left-click on a | 1782 | /* rclick on hold requires that we fire left-click on a |
@@ -1777,32 +1792,24 @@ static int process_input(int tmo, bool do_pausemenu) | |||
1777 | } | 1792 | } |
1778 | else | 1793 | else |
1779 | { | 1794 | { |
1780 | if(pressed & BTN_FIRE) | 1795 | if(pressed & BTN_FIRE) { |
1781 | send_click(LEFT_BUTTON, false); | 1796 | send_click(LEFT_BUTTON, false); |
1797 | accept_input = false; | ||
1798 | } | ||
1782 | else if(released & BTN_FIRE) | 1799 | else if(released & BTN_FIRE) |
1783 | send_click(LEFT_RELEASE, false); | 1800 | send_click(LEFT_RELEASE, false); |
1784 | else if(button & BTN_FIRE) | 1801 | else if(button & BTN_FIRE) |
1785 | send_click(LEFT_DRAG, false); | 1802 | send_click(LEFT_DRAG, false); |
1786 | } | 1803 | } |
1787 | 1804 | ||
1788 | /* acceleration */ | 1805 | if(!button) |
1789 | if(state && state == last_mousedir) | ||
1790 | { | ||
1791 | if(++held_count % 5 == 0 && v < 15) | ||
1792 | v++; | ||
1793 | } | ||
1794 | else | ||
1795 | { | 1806 | { |
1796 | if(!button) | 1807 | LOGF("all keys released, accepting further input"); |
1797 | { | 1808 | accept_input = true; |
1798 | LOGF("all keys released, accepting further input"); | ||
1799 | accept_input = true; | ||
1800 | } | ||
1801 | last_mousedir = state; | ||
1802 | v = 1; | ||
1803 | held_count = 0; | ||
1804 | } | 1809 | } |
1805 | 1810 | ||
1811 | last_keystate = button; | ||
1812 | |||
1806 | /* no buttons are sent to the midend in mouse mode */ | 1813 | /* no buttons are sent to the midend in mouse mode */ |
1807 | return 0; | 1814 | return 0; |
1808 | } | 1815 | } |
@@ -1972,6 +1979,18 @@ static int process_input(int tmo, bool do_pausemenu) | |||
1972 | return state; | 1979 | return state; |
1973 | } | 1980 | } |
1974 | 1981 | ||
1982 | static void zoom_clamp_panning(void) { | ||
1983 | if(zoom_y < 0) | ||
1984 | zoom_y = 0; | ||
1985 | if(zoom_x < 0) | ||
1986 | zoom_x = 0; | ||
1987 | |||
1988 | if(zoom_y + LCD_HEIGHT >= zoom_h) | ||
1989 | zoom_y = zoom_h - LCD_HEIGHT; | ||
1990 | if(zoom_x + LCD_WIDTH >= zoom_w) | ||
1991 | zoom_x = zoom_w - LCD_WIDTH; | ||
1992 | } | ||
1993 | |||
1975 | /* This function handles zoom mode, where the user can either pan | 1994 | /* This function handles zoom mode, where the user can either pan |
1976 | * around a zoomed-in image or play a zoomed-in version of the game. */ | 1995 | * around a zoomed-in image or play a zoomed-in version of the game. */ |
1977 | static void zoom(void) | 1996 | static void zoom(void) |
@@ -2001,13 +2020,21 @@ static void zoom(void) | |||
2001 | return; | 2020 | return; |
2002 | } | 2021 | } |
2003 | 2022 | ||
2023 | /* set position */ | ||
2024 | |||
2025 | if(zoom_x < 0) { | ||
2026 | /* first run */ | ||
2027 | zoom_x = zoom_w / 2 - LCD_WIDTH / 2; | ||
2028 | zoom_y = zoom_h / 2 - LCD_HEIGHT / 2; | ||
2029 | } | ||
2030 | |||
2031 | zoom_clamp_panning(); | ||
2032 | |||
2004 | zoom_enabled = true; | 2033 | zoom_enabled = true; |
2005 | 2034 | ||
2006 | /* draws go to the zoom framebuffer */ | 2035 | /* draws go to the zoom framebuffer */ |
2007 | midend_force_redraw(me); | 2036 | midend_force_redraw(me); |
2008 | 2037 | ||
2009 | zoom_x = zoom_y = 0; | ||
2010 | |||
2011 | rb->lcd_bitmap_part(zoom_fb, zoom_x, zoom_y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h), | 2038 | rb->lcd_bitmap_part(zoom_fb, zoom_x, zoom_y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h), |
2012 | 0, 0, LCD_WIDTH, LCD_HEIGHT); | 2039 | 0, 0, LCD_WIDTH, LCD_HEIGHT); |
2013 | 2040 | ||
@@ -2031,18 +2058,25 @@ static void zoom(void) | |||
2031 | if(view_mode) | 2058 | if(view_mode) |
2032 | { | 2059 | { |
2033 | int button = rb->button_get_w_tmo(timer_on ? TIMER_INTERVAL : -1); | 2060 | int button = rb->button_get_w_tmo(timer_on ? TIMER_INTERVAL : -1); |
2061 | |||
2062 | exit_on_usb(button); | ||
2063 | |||
2034 | switch(button) | 2064 | switch(button) |
2035 | { | 2065 | { |
2036 | case BTN_UP: | 2066 | case BTN_UP: |
2067 | case BTN_UP | BUTTON_REPEAT: | ||
2037 | zoom_y -= PAN_Y; /* clamped later */ | 2068 | zoom_y -= PAN_Y; /* clamped later */ |
2038 | break; | 2069 | break; |
2039 | case BTN_DOWN: | 2070 | case BTN_DOWN: |
2071 | case BTN_DOWN | BUTTON_REPEAT: | ||
2040 | zoom_y += PAN_Y; /* clamped later */ | 2072 | zoom_y += PAN_Y; /* clamped later */ |
2041 | break; | 2073 | break; |
2042 | case BTN_LEFT: | 2074 | case BTN_LEFT: |
2075 | case BTN_LEFT | BUTTON_REPEAT: | ||
2043 | zoom_x -= PAN_X; /* clamped later */ | 2076 | zoom_x -= PAN_X; /* clamped later */ |
2044 | break; | 2077 | break; |
2045 | case BTN_RIGHT: | 2078 | case BTN_RIGHT: |
2079 | case BTN_RIGHT | BUTTON_REPEAT: | ||
2046 | zoom_x += PAN_X; /* clamped later */ | 2080 | zoom_x += PAN_X; /* clamped later */ |
2047 | break; | 2081 | break; |
2048 | case BTN_PAUSE: | 2082 | case BTN_PAUSE: |
@@ -2050,22 +2084,15 @@ static void zoom(void) | |||
2050 | sfree(zoom_fb); | 2084 | sfree(zoom_fb); |
2051 | fix_size(); | 2085 | fix_size(); |
2052 | return; | 2086 | return; |
2053 | case BTN_FIRE: | 2087 | case BTN_FIRE | BUTTON_REL: |
2088 | /* state change to interaction mode */ | ||
2054 | view_mode = false; | 2089 | view_mode = false; |
2055 | continue; | 2090 | break; |
2056 | default: | 2091 | default: |
2057 | break; | 2092 | break; |
2058 | } | 2093 | } |
2059 | 2094 | ||
2060 | if(zoom_y < 0) | 2095 | zoom_clamp_panning(); |
2061 | zoom_y = 0; | ||
2062 | if(zoom_x < 0) | ||
2063 | zoom_x = 0; | ||
2064 | |||
2065 | if(zoom_y + LCD_HEIGHT >= zoom_h) | ||
2066 | zoom_y = zoom_h - LCD_HEIGHT; | ||
2067 | if(zoom_x + LCD_WIDTH >= zoom_w) | ||
2068 | zoom_x = zoom_w - LCD_WIDTH; | ||
2069 | 2096 | ||
2070 | if(timer_on) | 2097 | if(timer_on) |
2071 | timer_cb(); | 2098 | timer_cb(); |
@@ -2081,9 +2108,23 @@ static void zoom(void) | |||
2081 | } | 2108 | } |
2082 | else | 2109 | else |
2083 | { | 2110 | { |
2111 | /* The cursor is always in screenspace coordinates; when | ||
2112 | * zoomed, this means the mouse is always restricted to | ||
2113 | * the bounds of the physical display, not the virtual | ||
2114 | * zoom framebuffer. */ | ||
2115 | if(mouse_mode) | ||
2116 | draw_mouse(); | ||
2117 | |||
2118 | rb->lcd_update(); | ||
2119 | |||
2120 | if(mouse_mode) | ||
2121 | clear_mouse(); | ||
2122 | |||
2084 | /* basically a copy-pasta'd main loop */ | 2123 | /* basically a copy-pasta'd main loop */ |
2085 | int button = process_input(timer_on ? TIMER_INTERVAL : -1, false); | 2124 | int button = process_input(timer_on ? TIMER_INTERVAL : -1, false); |
2086 | 2125 | ||
2126 | exit_on_usb(button); | ||
2127 | |||
2087 | if(button < 0) | 2128 | if(button < 0) |
2088 | { | 2129 | { |
2089 | view_mode = true; | 2130 | view_mode = true; |
@@ -2104,18 +2145,6 @@ static void zoom(void) | |||
2104 | 2145 | ||
2105 | draw_title(false); | 2146 | draw_title(false); |
2106 | 2147 | ||
2107 | /* The cursor is always in screenspace coordinates; when | ||
2108 | * zoomed, this means the mouse is always restricted to | ||
2109 | * the bounds of the physical display, not the virtual | ||
2110 | * zoom framebuffer. */ | ||
2111 | if(mouse_mode) | ||
2112 | draw_mouse(); | ||
2113 | |||
2114 | rb->lcd_update(); | ||
2115 | |||
2116 | if(mouse_mode) | ||
2117 | clear_mouse(); | ||
2118 | |||
2119 | rb->yield(); | 2148 | rb->yield(); |
2120 | } | 2149 | } |
2121 | } | 2150 | } |