diff --git a/apps/plugin.c b/apps/plugin.c index 35b4179949..52565b82cc 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -668,6 +668,8 @@ static const struct plugin_api rockbox_api = { #if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID) usb_hid_send, #endif + + lcd_set_viewport, }; int plugin_load(const char* plugin, const void* parameter) diff --git a/apps/plugin.h b/apps/plugin.h index 3809486d0a..d2130f48df 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -836,6 +836,8 @@ struct plugin_api { #if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID) void (*usb_hid_send)(usage_page_t usage_page, int id); #endif + + void (*lcd_set_viewport)(struct viewport* vp); }; /* plugin header */ diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c index 2c16e03c9c..079a6e500c 100644 --- a/apps/plugins/calculator.c +++ b/apps/plugins/calculator.c @@ -365,7 +365,7 @@ PLUGIN_HEADER #define CALCULATOR_CLEAR BUTTON_TOPRIGHT #endif -#include "lib/touchscreen.h" +#include "lib/pluginlib_touchscreen.h" static struct ts_raster calc_raster = { X_0_POS, Y_1_POS, BUTTON_COLS*REC_WIDTH, BUTTON_ROWS*REC_HEIGHT, REC_WIDTH, REC_HEIGHT }; #endif diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 72538fc2a0..00d3ac7c56 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES @@ -54,7 +54,7 @@ pluginlib_albumart.c pluginlib_actions.c helper.c #ifdef HAVE_TOUCHSCREEN -touchscreen.c +pluginlib_touchscreen.c #endif md5.c diff --git a/apps/plugins/lib/pluginlib_touchscreen.c b/apps/plugins/lib/pluginlib_touchscreen.c new file mode 100644 index 0000000000..eb023b064c --- /dev/null +++ b/apps/plugins/lib/pluginlib_touchscreen.c @@ -0,0 +1,249 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2008 by Maurus Cuelenaere +* Copyright (C) 2009 by Karl Kurbjun +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#include "plugin.h" + +#ifdef HAVE_TOUCHSCREEN + +#include "pluginlib_touchscreen.h" + +/******************************************************************************* + * Touchbutton functions: These functions allow the plugin to specify a button + * location that, in turn gets mapped to a button press return value. + ******************************************************************************/ + +/* touchbutton_get: + * This function checks the touchbutton structure passed to it for hits. When + * one is found it returns action. + * inputs: + * struct touchbutton *data: This is intended to be an array of + * touchbuttons of size num_buttons. Each element in the array defines + * one button. + * int button: This is the button return value from a button_get() call. + * It is used to determine REPEAT/RELEASE events. + * int num_buttons: This tells touchbutton_get how many elements are in + * data. + * return: + * If a touch occured over one of the defined buttons, return action, else + * return 0. + */ +int touchbutton_get(struct touchbutton *data, int button, int num_buttons) { + short x,y; + + /* Get the x/y location of the button press, this is set by button_get when + * a button is pulled from the queue. + */ + x = rb->button_get_data() >> 16; + y = (short) rb->button_get_data(); + struct viewport *v; + + int i; + + /* Loop over the data array to check if any of the buttons were pressed */ + for (i=0; i= v->x && x < (v->x + v->width) && + y >= v->y && y < (v->y + v->height) ) { + if( ((button & BUTTON_REPEAT) && data[i].repeat) || + ((button & BUTTON_REL) && !data[i].repeat) ) { + return data[i].action; + } + } + } + return 0; +} + +/* touchbutton_draw: + * This function draws the button with the associated text as long as the + * invisible flag is not set. Support for pixmaps needs to be added. + * inputs: + * struct touchbutton *data: This is intended to be an array of + * touchbuttons of size num_buttons. Each element in the array defines + * one button. + * int num_buttons: This tells touchbutton_get how many elements are in + * data. + * return: + * If a touch occured over one of the defined buttons, return action, else + * return 0. + */ +void touchbutton_draw(struct touchbutton *data, int num_buttons) { + int i; + /* These store the width and height of the title offset */ + int title_width, title_height; + + /* Loop over all the elements in data */ + for(i=0; ilcd_set_viewport(&data[i].vp); + + /* Get the string size so that the title can be centered. */ + rb->lcd_getstringsize(data[i].title, &title_width, &title_height); + + /* Center the title vertically */ + title_height=(data[i].vp.height-title_height)/2; + + /* If the above calculation was negative, reset to 0 */ + if(title_height<0) { + title_height=0; + } + + /* Center the title horizontally */ + title_width=(data[i].vp.width-title_width)/2; + + /* If the above calculation was negative, reset to 0 */ + if(title_width<0) { + title_width=0; + } + + /* If the width offset was 0, use a scrolling puts, else center and + * print the title. + */ + if(title_width==0) { + rb->lcd_puts_scroll(0, 0, data[i].title); + } else { + rb->lcd_putsxy(title_width, title_height, data[i].title); + } + + /* Draw bounding box around the button location. */ + rb->lcd_drawrect( 0, 0, data[i].vp.width, data[i].vp.height); + } + } + rb->lcd_set_viewport(NULL); /* Go back to the default viewport */ +} + +/******************************************************************************* + * Touchmap functions: Not sure how exactly these functions are used, comments + * needed!!! + ******************************************************************************/ +unsigned int touchscreen_map(struct ts_mappings *map, int x, int y) +{ + int i; + for(i=0; i < map->amount; i++) + { + #define _MAP(x) (map->mappings[x]) + if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width) + && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height)) + return i; + } + + return -1; +} + +unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result) +{ + int res1_x, res2_x, res1_y, res2_y; + + if((x - map->tl_x) < 0 || + (x - map->tl_x) > map->width) + return -1; + res1_x = (x - map->tl_x)/(map->raster_width); + res2_x = (x - map->tl_x)%(map->raster_width); + + if((y - map->tl_y) < 0 || + (y - map->tl_y) > map->height) + return -1; + res1_y = (y - map->tl_y)/(map->raster_height); + res2_y = (y - map->tl_y)%(map->raster_height); + + if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */ + return -2; + else + { + (*result).x = res1_x; + (*result).y = res1_y; + return 1; + } +} + +struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button) +{ + struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}}; + struct ts_raster_result tmp; + + ret.action = TS_ACTION_NONE; + if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1) + return ret; + + #define NOT_HANDLED (ret.action == TS_ACTION_NONE) + if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable) + { + map->_prev_x = tmp.x; + map->_prev_y = tmp.y; + } + if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable) + { + ret.action = TS_ACTION_DRAG_DROP; + ret.from.x = map->_prev_x; + ret.from.y = map->_prev_y; + ret.to.x = tmp.x; + ret.to.y = tmp.y; + } + if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED) + { + if(map->_prev_x == tmp.x && map->_prev_y == tmp.y) + { + ret.action = TS_ACTION_DOUBLE_CLICK; + ret.from.x = ret.to.x = tmp.x; + ret.from.y = ret.to.y = tmp.y; + } + else + { + map->_prev_x = tmp.x; + map->_prev_y = tmp.y; + } + } + if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED) + { + if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y)) + { + ret.action = TS_ACTION_TWO_D_MOVEMENT; + ret.from.x = map->two_d_from.x; + ret.from.y = map->two_d_from.y; + ret.to.x = map->two_d_from.x + (map->two_d_from.x == tmp.x ? 0 : (tmp.x > map->two_d_from.x ? 1 : -1)); + ret.to.y = map->two_d_from.y + (map->two_d_from.y == tmp.y ? 0 : (tmp.y > map->two_d_from.y ? 1 : -1)); + } + else + ret.action = TS_ACTION_NONE; + } + if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED) + { + ret.action = TS_ACTION_CLICK; + ret.from.x = ret.to.x = tmp.x; + ret.from.y = ret.to.y = tmp.y; + } + if(map->move_progress_enable && NOT_HANDLED) + { + ret.action = TS_ACTION_MOVE; + ret.from.x = ret.to.x = tmp.x; + ret.from.y = ret.to.y = tmp.y; + } + + map->_prev_btn_state = button; + return ret; +} + +#endif /* HAVE_TOUCHSCREEN */ diff --git a/apps/plugins/lib/touchscreen.h b/apps/plugins/lib/pluginlib_touchscreen.h similarity index 70% rename from apps/plugins/lib/touchscreen.h rename to apps/plugins/lib/pluginlib_touchscreen.h index cd5251e46f..f2787655ee 100644 --- a/apps/plugins/lib/touchscreen.h +++ b/apps/plugins/lib/pluginlib_touchscreen.h @@ -8,6 +8,7 @@ * $Id$ * * Copyright (C) 2008 by Maurus Cuelenaere +* Copyright (C) 2009 by Karl Kurbjun * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,6 +27,28 @@ #ifdef HAVE_TOUCHSCREEN +/******************************************************************************* + * Touchbutton + ******************************************************************************/ +struct touchbutton { + /* Each button has it's own viewport to define colors, drawstyle, location*/ + struct viewport vp; + bool repeat; /* requires the area be held for the action */ + int action; /* action this button will return */ + bool invisible; /* Is this an invisible button? */ + char *title; /* Specify a title */ + fb_data *pixmap; /* Currently unused, but will allow for a graphic */ +}; + +/* Get: tests for a button press and returns action. */ +int touchbutton_get(struct touchbutton *data, int button, int num_buttons); +/* Draw: Draws all visible buttons */ +void touchbutton_draw(struct touchbutton *data, int num_buttons); + + +/******************************************************************************* + * Touch mapping + ******************************************************************************/ struct ts_mapping { int tl_x; /* top left */ diff --git a/apps/plugins/lib/touchscreen.c b/apps/plugins/lib/touchscreen.c deleted file mode 100644 index 5b7517349a..0000000000 --- a/apps/plugins/lib/touchscreen.c +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Copyright (C) 2008 by Maurus Cuelenaere -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#include "plugin.h" - -#ifdef HAVE_TOUCHSCREEN - -#include "touchscreen.h" - -unsigned int touchscreen_map(struct ts_mappings *map, int x, int y) -{ - int i; - for(i=0; i < map->amount; i++) - { - #define _MAP(x) (map->mappings[x]) - if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width) - && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height)) - return i; - } - - return -1; -} - -unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result) -{ - int res1_x, res2_x, res1_y, res2_y; - - if((x - map->tl_x) < 0 || - (x - map->tl_x) > map->width) - return -1; - res1_x = (x - map->tl_x)/(map->raster_width); - res2_x = (x - map->tl_x)%(map->raster_width); - - if((y - map->tl_y) < 0 || - (y - map->tl_y) > map->height) - return -1; - res1_y = (y - map->tl_y)/(map->raster_height); - res2_y = (y - map->tl_y)%(map->raster_height); - - if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */ - return -2; - else - { - (*result).x = res1_x; - (*result).y = res1_y; - return 1; - } -} - -struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button) -{ - struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}}; - struct ts_raster_result tmp; - - ret.action = TS_ACTION_NONE; - if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1) - return ret; - - #define NOT_HANDLED (ret.action == TS_ACTION_NONE) - if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable) - { - map->_prev_x = tmp.x; - map->_prev_y = tmp.y; - } - if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable) - { - ret.action = TS_ACTION_DRAG_DROP; - ret.from.x = map->_prev_x; - ret.from.y = map->_prev_y; - ret.to.x = tmp.x; - ret.to.y = tmp.y; - } - if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED) - { - if(map->_prev_x == tmp.x && map->_prev_y == tmp.y) - { - ret.action = TS_ACTION_DOUBLE_CLICK; - ret.from.x = ret.to.x = tmp.x; - ret.from.y = ret.to.y = tmp.y; - } - else - { - map->_prev_x = tmp.x; - map->_prev_y = tmp.y; - } - } - if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED) - { - if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y)) - { - ret.action = TS_ACTION_TWO_D_MOVEMENT; - ret.from.x = map->two_d_from.x; - ret.from.y = map->two_d_from.y; - ret.to.x = map->two_d_from.x + (map->two_d_from.x == tmp.x ? 0 : (tmp.x > map->two_d_from.x ? 1 : -1)); - ret.to.y = map->two_d_from.y + (map->two_d_from.y == tmp.y ? 0 : (tmp.y > map->two_d_from.y ? 1 : -1)); - } - else - ret.action = TS_ACTION_NONE; - } - if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED) - { - ret.action = TS_ACTION_CLICK; - ret.from.x = ret.to.x = tmp.x; - ret.from.y = ret.to.y = tmp.y; - } - if(map->move_progress_enable && NOT_HANDLED) - { - ret.action = TS_ACTION_MOVE; - ret.from.x = ret.to.x = tmp.x; - ret.from.y = ret.to.y = tmp.y; - } - - map->_prev_btn_state = button; - return ret; -} - -#endif /* HAVE_TOUCHSCREEN */ diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c index 5bd38dc244..47be0ea309 100644 --- a/apps/plugins/minesweeper.c +++ b/apps/plugins/minesweeper.c @@ -340,7 +340,7 @@ char str[30]; #ifdef HAVE_TOUCHSCREEN -#include "lib/touchscreen.h" +#include "lib/pluginlib_touchscreen.h" static struct ts_raster mine_raster = { 0, 0, MAX_WIDTH, MAX_HEIGHT, TileSize, TileSize }; #endif diff --git a/apps/plugins/pegbox.c b/apps/plugins/pegbox.c index 67714fee9d..cd90de49c6 100644 --- a/apps/plugins/pegbox.c +++ b/apps/plugins/pegbox.c @@ -520,7 +520,7 @@ PLUGIN_HEADER #ifdef HAVE_TOUCHSCREEN -#include "lib/touchscreen.h" +#include "lib/pluginlib_touchscreen.h" static struct ts_raster pegbox_raster = { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT, PIECE_WIDTH, PIECE_HEIGHT }; diff --git a/apps/plugins/reversi/reversi-gui.c b/apps/plugins/reversi/reversi-gui.c index 2ad27caf01..fa20e46bb6 100644 --- a/apps/plugins/reversi/reversi-gui.c +++ b/apps/plugins/reversi/reversi-gui.c @@ -32,11 +32,9 @@ Use the arrow keys to move cursor, and press TOGGLE to place a stone. At any time during the game, press MENU to bring up the game menu with further options: - - Save - Reload - Clear - */ #include "plugin.h" @@ -139,6 +137,75 @@ static cursor_wrap_mode_t cursor_wrap_mode; static bool quit_plugin; static bool game_finished; +#ifdef HAVE_TOUCHSCREEN +#include "lib/pluginlib_touchscreen.h" +/* This uses the touchscreen library functions/structures. */ + +/* This defines the number of buttons used; only used in this C file. */ +#define TOUCHBUTTON_COUNT 3 + +/* Define the button locations, widths and heights */ + +#if LCD_HEIGHT < LCD_WIDTH +/* Define Menu button x, y, width, height */ +#define B_MENU_X LEGEND_X(0) +#define B_MENU_Y (LCD_HEIGHT/4) +#define B_MENU_W (LCD_WIDTH-LEGEND_X(0)) +#define B_MENU_H (LCD_HEIGHT/4) +/* Define Quit Button x, y, width, height */ +#define B_QUIT_X LEGEND_X(0) +#define B_QUIT_Y (LCD_HEIGHT/2) +#define B_QUIT_W (LCD_WIDTH-LEGEND_X(0)) +#define B_QUIT_H (LCD_HEIGHT/4) +#else +/* Define Menu button x, y, width, height */ +#define B_MENU_X (LCD_WIDTH/2) +#define B_MENU_Y LEGEND_Y(0) +#define B_MENU_W (LCD_WIDTH/4) +#define B_MENU_H (2*CELL_HEIGHT) +/* Define Quit Button x, y, width, height */ +#define B_QUIT_X (LCD_WIDTH-LCD_WIDTH/4) +#define B_QUIT_Y LEGEND_Y(0) +#define B_QUIT_W (LCD_WIDTH/4) +#define B_QUIT_H (2*CELL_HEIGHT) +#endif + +/* This is the button initialization/definition. The first element is the + * Viewport. This is defined in lcd.h, but the elements are: + * int x - X location of button/viewport + * int y - Y location of button/viewport + * int width - Width of button/viewport + * int height - Height of button/viewport + * int font - Font to be used on button/viewport + * int drawmode- Modes defined in lcd.h + * unsigned fg_pattern - foreground color + * unsigned bg_pattern - backbround color + * unsigned lss_pattern - Selector colors (currently unused) + * unsigned lse_pattern - | + * unsigned lst_pattern - \/ + * + * The rest of the touch button elements are: + * bool repeat - requires the area be held for the action + * int action - action this button will return + * bool invisible - Is this an invisible button? + * char *title - Specify a title + * fb_data *pixmap- Currently unused, but will allow for a graphic + */ +struct touchbutton reversi_buttons[TOUCHBUTTON_COUNT] = + { + { {B_MENU_X, B_MENU_Y, B_MENU_W, B_MENU_H, FONT_UI, + STYLE_DEFAULT, 0, 0xFFFF, 0, 0, 0}, + false, REVERSI_BUTTON_MENU, false, "Menu", NULL }, + + { {B_QUIT_X, B_QUIT_Y, B_QUIT_W, B_QUIT_H, FONT_UI, + STYLE_DEFAULT, 0, 0xFFFF, 0, 0, 0}, + false, REVERSI_BUTTON_QUIT, false, "Quit", NULL }, + + { {0, 0, XOFS+BOARD_WIDTH, YOFS+BOARD_HEIGHT, 0, + STYLE_DEFAULT, 0, 0xFFFF, 0, 0, 0}, + false, REVERSI_BUTTON_MAKE_MOVE, true, NULL, NULL } +}; +#endif /* Initialises the state of the game (starts a new game) */ static void reversi_gui_init(void) { @@ -184,8 +251,12 @@ static void reversi_gui_draw_cell(int x, int y, int color) { int i; if (color == WHITE) { for (i = 0; i < CELL_LINE_THICKNESS; i++) { - rb->lcd_drawrect(x+STONE_MARGIN+i, y+STONE_MARGIN+i, - CELL_WIDTH+1-2*(STONE_MARGIN+i), CELL_HEIGHT+1-2*(STONE_MARGIN+i)); + rb->lcd_drawrect( + x+STONE_MARGIN+i, + y+STONE_MARGIN+i, + CELL_WIDTH+1-2*(STONE_MARGIN+i), + CELL_HEIGHT+1-2*(STONE_MARGIN+i) + ); } } else if (color == BLACK) { rb->lcd_fillrect(x+STONE_MARGIN, y+STONE_MARGIN, @@ -249,6 +320,10 @@ static void reversi_gui_display_board(void) { y = LEGEND_Y(r); rb->lcd_drawrect(x, y, CELL_WIDTH+1, CELL_HEIGHT+1); +#if defined(HAVE_TOUCHSCREEN) + touchbutton_draw(reversi_buttons, TOUCHBUTTON_COUNT); +#endif + /* Update the screen */ rb->lcd_update(); } @@ -299,7 +374,10 @@ static bool reversi_gui_choose_strategy( break; } } - result = rb->set_option(prompt, &index, INT, strategy_settings, num_items, NULL); + + result = + rb->set_option(prompt, &index, INT, strategy_settings, num_items, NULL); + (*player) = strategy_values[index]; if((*player)->init_func) @@ -339,7 +417,8 @@ static bool reversi_gui_menu(void) { break; case 4: /* Cursor wrap mode */ - num_items = sizeof(cursor_wrap_mode_values)/sizeof(cursor_wrap_mode_values[0]); + num_items = sizeof(cursor_wrap_mode_values) / + sizeof(cursor_wrap_mode_values[0]); index = 0; for (i = 0; i < num_items; i++) { if (cursor_wrap_mode == cursor_wrap_mode_values[i]) { @@ -372,7 +451,8 @@ static bool reversi_gui_menu(void) { * Returns true iff the cursor would be really moved. In any case, the * new cursor position is stored in (new_row, new_col). */ -static bool reversi_gui_cursor_pos_vmove(int row_delta, int *new_row, int *new_col) { +static bool +reversi_gui_cursor_pos_vmove(int row_delta, int *new_row, int *new_col) { *new_row = cur_row + row_delta; *new_col = cur_col; @@ -421,7 +501,8 @@ static bool reversi_gui_cursor_pos_vmove(int row_delta, int *new_row, int *new_c * Returns true iff the cursor would be really moved. In any case, the * new cursor position is stored in (new_row, new_col). */ -static bool reversi_gui_cursor_pos_hmove(int col_delta, int *new_row, int *new_col) { +static bool +reversi_gui_cursor_pos_hmove(int col_delta, int *new_row, int *new_col) { *new_row = cur_row; *new_col = cur_col + col_delta; @@ -554,39 +635,62 @@ enum plugin_status plugin_start(const void *parameter) { continue; } + /*********************************************************************** + * Button handling code happens below here + **********************************************************************/ button = rb->button_get(true); + + /* The touchscreen buttons can act as true buttons so OR them in */ +#ifdef HAVE_TOUCHSCREEN + button |= touchbutton_get(reversi_buttons, button, TOUCHBUTTON_COUNT); +#endif - switch (button) { + /* All of these button presses wait for the release event */ + if(button&BUTTON_REL) { #ifdef REVERSI_BUTTON_QUIT - /* Exit game */ - case REVERSI_BUTTON_QUIT: + if(button&REVERSI_BUTTON_QUIT) { exit = true; - break; + } #endif #ifdef HAVE_TOUCHSCREEN - case BUTTON_TOUCHSCREEN: - button_x = rb->button_get_data() >> 16; - button_y = rb->button_get_data() & 0xffff; - if( (CELL_R(button_y)>(BOARD_SIZE-1)) || - (CELL_C(button_x)>(BOARD_SIZE-1)) ) + if(button&BUTTON_TOUCHSCREEN) { + button_x = rb->button_get_data(); + button_y = button_x & 0xffff; + button_x >>= 16; + + /* Check if the click was in the gameboard, if so move cursor. + * This has to happen before MAKE_MOVE is processed. + */ + if( (CELL_R(button_y) 0) { /* Move was made. Global changes on the board are possible */ draw_screen = true; /* Redraw the screen next time */ @@ -607,66 +711,42 @@ enum plugin_status plugin_start(const void *parameter) { /* Ignore any button presses during the splash */ rb->button_clear_queue(); } - break; + } + } + + /* These button presses will run on a release or a repeat event */ + if(button&BUTTON_REL || button&BUTTON_REPEAT) { /* Move cursor left */ -#ifdef REVERSI_BUTTON_ALT_LEFT - case REVERSI_BUTTON_ALT_LEFT: - case (REVERSI_BUTTON_ALT_LEFT | BUTTON_REPEAT): -#endif - case REVERSI_BUTTON_LEFT: - case (REVERSI_BUTTON_LEFT | BUTTON_REPEAT): + if(button&REVERSI_BUTTON_LEFT) { if (reversi_gui_cursor_pos_hmove(-1, &row, &col)) { reversi_gui_move_cursor(row, col); } - break; - + } /* Move cursor right */ -#ifdef REVERSI_BUTTON_ALT_RIGHT - case REVERSI_BUTTON_ALT_RIGHT: - case (REVERSI_BUTTON_ALT_RIGHT | BUTTON_REPEAT): -#endif - case REVERSI_BUTTON_RIGHT: - case (REVERSI_BUTTON_RIGHT | BUTTON_REPEAT): + if(button&REVERSI_BUTTON_RIGHT) { if (reversi_gui_cursor_pos_hmove(1, &row, &col)) { reversi_gui_move_cursor(row, col); } - break; - + } /* Move cursor up */ - case REVERSI_BUTTON_UP: - case (REVERSI_BUTTON_UP | BUTTON_REPEAT): + if(button&REVERSI_BUTTON_UP) { if (reversi_gui_cursor_pos_vmove(-1, &row, &col)) { reversi_gui_move_cursor(row, col); } - break; - + } /* Move cursor down */ - case REVERSI_BUTTON_DOWN: - case (REVERSI_BUTTON_DOWN | BUTTON_REPEAT): + if(button&REVERSI_BUTTON_DOWN) { if (reversi_gui_cursor_pos_vmove(1, &row, &col)) { reversi_gui_move_cursor(row, col); } - break; - - case REVERSI_BUTTON_MENU: -#ifdef REVERSI_BUTTON_MENU_PRE - if (lastbutton != REVERSI_BUTTON_MENU_PRE) { - break; - } -#endif - if (reversi_gui_menu()) { - return PLUGIN_USB_CONNECTED; - } - draw_screen = true; - break; - - default: - if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { - /* Quit if USB has been connected */ - return PLUGIN_USB_CONNECTED; - } - break; + } } + + if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { + /* Quit if USB has been connected */ + return PLUGIN_USB_CONNECTED; + } + if (button != BUTTON_NONE) { lastbutton = button; } diff --git a/apps/plugins/reversi/reversi-gui.h b/apps/plugins/reversi/reversi-gui.h index 8c409e9a75..a93fa344e4 100644 --- a/apps/plugins/reversi/reversi-gui.h +++ b/apps/plugins/reversi/reversi-gui.h @@ -42,11 +42,10 @@ #define REVERSI_BUTTON_DOWN BUTTON_DOWN #define REVERSI_BUTTON_LEFT BUTTON_LEFT #define REVERSI_BUTTON_RIGHT BUTTON_RIGHT -#define REVERSI_BUTTON_MAKE_MOVE_PRE BUTTON_MENU -#define REVERSI_BUTTON_MAKE_MOVE (BUTTON_MENU | BUTTON_REL) -#define REVERSI_BUTTON_ALT_MAKE_MOVE (BUTTON_MENU | BUTTON_DOWN) -#define REVERSI_BUTTON_MENU_PRE BUTTON_MENU -#define REVERSI_BUTTON_MENU (BUTTON_MENU | BUTTON_REPEAT) +#define REVERSI_BUTTON_MAKE_MOVE BUTTON_MENU +#define REVERSI_BUTTON_MAKE_MOVE_SHORTPRESS +#define REVERSI_BUTTON_MENU_LONGPRESS +#define REVERSI_BUTTON_MENU BUTTON_MENU #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H300_PAD) @@ -63,10 +62,8 @@ (CONFIG_KEYPAD == IPOD_1G2G_PAD) #define REVERSI_BUTTON_UP BUTTON_MENU #define REVERSI_BUTTON_DOWN BUTTON_PLAY -#define REVERSI_BUTTON_LEFT BUTTON_LEFT -#define REVERSI_BUTTON_RIGHT BUTTON_RIGHT -#define REVERSI_BUTTON_ALT_LEFT BUTTON_SCROLL_BACK -#define REVERSI_BUTTON_ALT_RIGHT BUTTON_SCROLL_FWD +#define REVERSI_BUTTON_LEFT (BUTTON_LEFT | BUTTON_SCROLL_BACK) +#define REVERSI_BUTTON_RIGHT (BUTTON_RIGHT | BUTTON_SCROLL_FWD) #define REVERSI_BUTTON_MAKE_MOVE (BUTTON_SELECT | BUTTON_REL) #define REVERSI_BUTTON_MENU (BUTTON_MENU | BUTTON_SELECT) diff --git a/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c index 4def88c4f8..04acb71e45 100644 --- a/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c +++ b/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c @@ -110,16 +110,17 @@ inline bool button_hold(void) int button_read_device(int *data) { + static int old_data; int button_read = BUTTON_NONE; short touch_x, touch_y, touch_z1, touch_z2; static bool hold_button_old = false; - *data = 0; + *data = old_data; /* Handle touchscreen */ if (tsc2100_read_touch(&touch_x, &touch_y, &touch_z1, &touch_z2)) { - *data = touch_to_pixels(&touch_x, &touch_y); + old_data = *data = touch_to_pixels(&touch_x, &touch_y); button_read |= touchscreen_to_pixels(touch_x, touch_y, data); }