summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2003-06-29 21:10:27 +0000
committerBjörn Stenberg <bjorn@haxx.se>2003-06-29 21:10:27 +0000
commit020ab8f01ee369a1955d891e500edfbf22219b49 (patch)
treec281b05ca65833499b3fa0ce86bb182ea5b690f4 /apps
parent51119303bbf2534b830ed56d1972ac04dac634e4 (diff)
downloadrockbox-020ab8f01ee369a1955d891e500edfbf22219b49.tar.gz
rockbox-020ab8f01ee369a1955d891e500edfbf22219b49.zip
Frederic Dang Ngoc's 'Star' game. Very nice graphic effects.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3777 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/star.c786
1 files changed, 786 insertions, 0 deletions
diff --git a/apps/plugins/star.c b/apps/plugins/star.c
new file mode 100644
index 0000000000..961c17f143
--- /dev/null
+++ b/apps/plugins/star.c
@@ -0,0 +1,786 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 Frederic Dang Ngoc
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "plugin.h"
+#ifdef HAVE_LCD_BITMAP
+
+/* file which contains the levels */
+#define STAR_LEVELS_FILE "/.rockbox/star/levels.txt"
+
+/* title of the game */
+#define STAR_TITLE "Star"
+
+/* font used to display title */
+#define STAR_TITLE_FONT 2
+
+/* size of a level in file */
+#define STAR_LEVEL_SIZE ((STAR_WIDTH + 1) * STAR_HEIGHT + 1)
+
+/* size of the game board */
+#define STAR_WIDTH 16
+#define STAR_HEIGHT 9
+
+/* left and top margin */
+#define STAR_OFFSET_X 8
+#define STAR_OFFSET_Y 0
+
+/* number of level */
+#define STAR_LEVEL_COUNT 20
+
+/* size of a tile */
+#define STAR_TILE_SIZE 6
+
+/* values of object in the board */
+#define STAR_VOID '.'
+#define STAR_WALL '*'
+#define STAR_STAR 'o'
+#define STAR_BALL 'X'
+#define STAR_BLOCK 'x'
+
+/* sleep time between two frames */
+#define STAR_SLEEP 1
+
+/* value of ball and block control */
+#define STAR_CONTROL_BALL 0
+#define STAR_CONTROL_BLOCK 1
+
+/* position of the ball */
+static int ball_x, ball_y;
+
+/* position of the block */
+static int block_x, block_y;
+
+/* number of stars to get to finish the level */
+static int star_count;
+
+/* the object we control : ball or block */
+static int control;
+
+/* the current board */
+static char board[STAR_HEIGHT][STAR_WIDTH];
+
+/* bitmap of the wall */
+static unsigned char wall_bmp[STAR_TILE_SIZE]
+ = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
+
+/* bitmap of the star */
+static unsigned char star_bmp[STAR_TILE_SIZE]
+ = {0x00, 0x0c, 0x12, 0x12, 0x0c, 0x00};
+
+/* bitmap of the ball */
+static unsigned char ball_bmp[STAR_TILE_SIZE]
+ = {0x00, 0x0c, 0x1e, 0x1a, 0x0c, 0x00};
+
+/* bitmap of the block */
+static unsigned char block_bmp[STAR_TILE_SIZE]
+ = {0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00};
+
+/* bitmap of the arrow animation */
+static unsigned char arrow_bmp[4][7] =
+ {
+ {0x7f, 0x7f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08},
+ {0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x08, 0x08},
+ {0x1c, 0x1c, 0x1c, 0x1c, 0x08, 0x08, 0x08},
+ {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}
+ };
+
+/* sequence of the bitmap arrow to follow to do one turn */
+static unsigned char anim_arrow[8] = {0, 1, 2, 3, 2, 1, 0};
+
+/* current_level */
+static int current_level = 0;
+
+/* char font size */
+static int char_width = -1;
+static int char_height = -1;
+
+static struct plugin_api* rb;
+
+/* this arrays contains a group of levels loaded into memory */
+static unsigned char* levels =
+"****************\n"
+"*X**........o*x*\n"
+"*..........o.***\n"
+"*.......**o....*\n"
+"*...**.o......**\n"
+"**.o..o.....o..*\n"
+"*.o......o**.o.*\n"
+"*.....**o.....o*\n"
+"****************\n"
+"\n"
+".*..*.*.*...*.**\n"
+"*...o.........X*\n"
+"...*o..*o...o...\n"
+"*.*.o.....o..*.*\n"
+"......*...o...*.\n"
+"*....*x*..o....*\n"
+"...*..*.*...*oo*\n"
+"*.............*.\n"
+".*..*........*..\n"
+"\n"
+"****************\n"
+"*...........o*x*\n"
+"*...**......**X*\n"
+"*...*o.........*\n"
+"*.o.....o**...o*\n"
+"*.*o..o..o*..o**\n"
+"*.**o.*o..o.o***\n"
+"*o....**o......*\n"
+"****************\n"
+"\n"
+"****************\n"
+"*............*x*\n"
+"*.....*........*\n"
+"**o*o.o*o*o*o*o*\n"
+"*.*.*o.o*.*.*.**\n"
+"**o*o*o.o*o*o*o*\n"
+"*.....*........*\n"
+"*...*.......*X.*\n"
+"****************\n"
+"\n"
+".**************.\n"
+"*X..*...*..*...*\n"
+"*..*o.*.o..o.*.*\n"
+"**......*..*...*\n"
+"*o.*o*........**\n"
+"**.....*.o.*...*\n"
+"*o*..*.*.*...*x*\n"
+"*...*....o*..*o*\n"
+".**************.\n"
+"\n"
+"....************\n"
+"...*...o...*o.o*\n"
+"..*....o....*.**\n"
+".*.....o.......*\n"
+"*X.....o.......*\n"
+"**.....o..*...**\n"
+"*......o....*..*\n"
+"*x.*...o..**o..*\n"
+"****************\n"
+"\n"
+"****************\n"
+"*..............*\n"
+".**.***..*o.**o*\n"
+".*o..*o.*.*.*.*.\n"
+"..*..*..***.**..\n"
+".**..*..*o*.*o**\n"
+"*..............*\n"
+"*..X*o....x..*o*\n"
+"****************\n"
+"\n"
+"***************.\n"
+"*..o**.........*\n"
+"*..*o..**.o....*\n"
+"*..o**.*.*o....*\n"
+"**.....**..*o*.*\n"
+"**.*.......o*o.*\n"
+"*oxo*...o..*X*.*\n"
+"**.............*\n"
+".***************\n"
+"\n"
+"..*.***********.\n"
+".*o*o......*..X*\n"
+"*o.o*....o....*.\n"
+".*.*..o**..o*..*\n"
+"*..*o.*oxo....o*\n"
+"*.....o**.....*.\n"
+"*o*o.........*..\n"
+"*...........*...\n"
+".***********....\n"
+"\n"
+"....***********.\n"
+"*****.o........*\n"
+"*...x.***o.o*.o*\n"
+"*.o...*o.*o...*.\n"
+"*.....*..o..*.o*\n"
+"*o*o..*.o*..*X*.\n"
+".*o...***..***..\n"
+"*.........*.*.*.\n"
+".*********..*..*\n"
+"\n"
+"****************\n"
+"*......*......X*\n"
+"*..*oo.....oo.**\n"
+"**...o...**...o*\n"
+"*o....*o*oo..***\n"
+"**.**....**....*\n"
+"*o..o*.o....x.o*\n"
+"**o***....*...**\n"
+"***************.\n"
+"\n"
+"**.....**..****.\n"
+"*X*****o.***.o**\n"
+"*....oo.....o..*\n"
+"*.**..**o..*o*.*\n"
+"*.*.o.*.*o.**..*\n"
+"*.**..**...*x*.*\n"
+"*.....o........*\n"
+"*........o.....*\n"
+"****************\n"
+"\n"
+".**************.\n"
+"*.X*........o.**\n"
+"*.*...*o...o**.*\n"
+"*.......o....*.*\n"
+"*.o..........*o*\n"
+"*.*......o.....*\n"
+"**......o.o..*o*\n"
+"*x..*....o.*.*.*\n"
+".**************.\n"
+"\n"
+"****************\n"
+"*o*o........o*o*\n"
+"*.o*X......**..*\n"
+"*.x........o...*\n"
+"*........o*....*\n"
+"*......o.......*\n"
+"*.o*........*..*\n"
+"*o*o........o*o*\n"
+"****************\n"
+"\n"
+".******.********\n"
+"*.....o*.....o.*\n"
+"*.*.o.*..*...o.*\n"
+"*..X*...*oo.*o.*\n"
+".*.*...*.o..x*.*\n"
+"*o.......*..*o.*\n"
+".*......o.....*.\n"
+"*o............o*\n"
+"****************\n"
+"\n"
+"****************\n"
+"**.x*o.o......o*\n"
+"*o.Xo*o.......**\n"
+"**.***........**\n"
+"**.....o*o*....*\n"
+"*oo.......o*o..*\n"
+"**.o....****o..*\n"
+"**o*..*........*\n"
+"****************\n"
+"\n"
+"****************\n"
+"*.o*........*X.*\n"
+"*.*..o*oo*o..*.*\n"
+"*....*o**o*.o..*\n"
+"*.o*.......o*..*\n"
+"*..o*o....o*...*\n"
+"*.*..*.**o*..*.*\n"
+"*....o.*o...x..*\n"
+"****************\n"
+"\n"
+"****************\n"
+"*.o....o..x*...*\n"
+"*..*o*o...*o...*\n"
+"*...*o*....*o..*\n"
+"*...o..*...o*o.*\n"
+"*.*o*...*.o*...*\n"
+"*.o*o.*.o.*....*\n"
+"*o*X..*.....*..*\n"
+"****************\n"
+"\n"
+"****************\n"
+"*o...**.....**o*\n"
+"*.*..*......*o.*\n"
+"*.o*...o**..o..*\n"
+"*.*....*o......*\n"
+"*....*...o*....*\n"
+"*.**.o*.**o..*x*\n"
+"*.o*.*o.....**X*\n"
+"****************\n"
+"\n"
+"****************\n"
+"*...o*o........*\n"
+"**o..o*.**o...**\n"
+"*.*.*.o...*..*.*\n"
+"*.x.*..**..*.Xo*\n"
+"*.*..*...o.*.*.*\n"
+"**...o**.*o..o**\n"
+"*........o*o...*\n"
+"****************";
+
+/**
+ * Display text.
+ */
+static void star_display_text(char *str, bool waitkey)
+{
+ int chars_by_line;
+ int lines_by_screen;
+ int chars_for_line;
+ int current_line = 0;
+ int first_char_index = 0;
+ char *ptr_char;
+ char *ptr_line;
+ int i;
+ char line[255];
+ int key;
+
+ rb->lcd_clear_display();
+
+ chars_by_line = LCD_WIDTH / char_width;
+ lines_by_screen = LCD_HEIGHT / char_height;
+
+ do
+ {
+ ptr_char = str + first_char_index;
+ chars_for_line = 0;
+ i = 0;
+ ptr_line = line;
+ while (i < chars_by_line)
+ {
+ switch (*ptr_char)
+ {
+ case '\t':
+ case ' ':
+ *(ptr_line++) = ' ';
+ case '\n':
+ case '\0':
+ chars_for_line = i;
+ break;
+
+ default:
+ *(ptr_line++) = *ptr_char;
+ }
+ if (*ptr_char == '\n' || *ptr_char == '\0')
+ break;
+ ptr_char++;
+ i++;
+ }
+
+ if (chars_for_line == 0)
+ chars_for_line = i;
+
+ line[chars_for_line] = '\0';
+
+ // test if we have cutted a word. If it is the case we don't have to
+ // skip the space
+ if (i == chars_by_line && chars_for_line == chars_by_line)
+ first_char_index += chars_for_line;
+ else
+ first_char_index += chars_for_line + 1;
+
+ // print the line on the screen
+ rb->lcd_putsxy(0, current_line * char_height, line);
+
+ // if the number of line showed on the screen is equals to the
+ // maximum number of line we can show, we wait for a key pressed to
+ // clear and show the remaining text.
+ current_line++;
+ if (current_line == lines_by_screen || *ptr_char == '\0')
+ {
+ current_line = 0;
+ rb->lcd_update();
+ if (waitkey)
+ while ((key = rb->button_get(true)) != BUTTON_PLAY
+ && key != BUTTON_ON
+ && key != BUTTON_DOWN);
+ rb->lcd_clear_display();
+ }
+ } while (*ptr_char != '\0');
+}
+
+/**
+ * Do a pretty transition from one level to another.
+ */
+static void star_transition_update(void)
+{
+ int center_x = LCD_WIDTH / 2;
+ int lcd_demi_width = LCD_WIDTH / 2;
+ int center_y = LCD_HEIGHT / 2;
+ int x;
+ int y = 0;
+ int var_y = 0;
+
+ for (x = 0 ; x < lcd_demi_width ; x++)
+ {
+ var_y += LCD_HEIGHT;
+ if (var_y > LCD_WIDTH)
+ {
+ var_y -= LCD_WIDTH;
+ y++;
+ }
+ rb->lcd_update_rect(center_x - x, center_y - y,
+ x * 2, y * 2);
+ rb->sleep(STAR_SLEEP);
+ }
+ rb->lcd_update();
+}
+
+/**
+ * Display information board of the current level.
+ */
+static void star_display_board_info(void)
+{
+ int label_offset_y = label_offset_y = LCD_HEIGHT - char_height;
+ char str_info[32];
+
+ rb->snprintf(str_info, sizeof(str_info), "L:%02d S:%02d C:",
+ current_level, star_count);
+ rb->lcd_putsxy(0, label_offset_y, str_info);
+
+ if (control == STAR_CONTROL_BALL)
+ rb->lcd_bitmap (ball_bmp, 103, label_offset_y + 1, STAR_TILE_SIZE,
+ STAR_TILE_SIZE, true);
+ else
+ rb->lcd_bitmap (block_bmp, 103, label_offset_y + 1, STAR_TILE_SIZE,
+ STAR_TILE_SIZE, true);
+
+ rb->lcd_update_rect(0, label_offset_y, LCD_WIDTH, char_height);
+}
+
+
+/**
+ * Load a level into board array.
+ */
+static int star_load_level(int current_level)
+{
+ int x, y;
+ char *ptr_tab;
+
+ ptr_tab = levels + current_level * STAR_LEVEL_SIZE;
+ control = STAR_CONTROL_BALL;
+ star_count = 0;
+
+ rb->lcd_clear_display();
+
+ for (y = 0 ; y < STAR_HEIGHT ; y++)
+ {
+ for (x = 0 ; x < STAR_WIDTH ; x++)
+ {
+ board[y][x] = *ptr_tab;
+ switch (*ptr_tab)
+ {
+ case STAR_VOID:
+ break;
+
+ case STAR_WALL:
+ rb->lcd_bitmap (wall_bmp,
+ STAR_OFFSET_X + x * STAR_TILE_SIZE,
+ STAR_OFFSET_Y + y * STAR_TILE_SIZE,
+ STAR_TILE_SIZE, STAR_TILE_SIZE, false);
+ break;
+
+ case STAR_STAR:
+ rb->lcd_bitmap (star_bmp,
+ STAR_OFFSET_X + x * STAR_TILE_SIZE,
+ STAR_OFFSET_Y + y * STAR_TILE_SIZE,
+ STAR_TILE_SIZE, STAR_TILE_SIZE, false);
+ star_count++;
+ break;
+
+ case STAR_BALL:
+ ball_x = x;
+ ball_y = y;
+ rb->lcd_bitmap (ball_bmp,
+ STAR_OFFSET_X + x * STAR_TILE_SIZE,
+ STAR_OFFSET_Y + y * STAR_TILE_SIZE,
+ STAR_TILE_SIZE, STAR_TILE_SIZE, false);
+ break;
+
+
+ case STAR_BLOCK:
+ block_x = x;
+ block_y = y;
+ rb->lcd_bitmap (block_bmp,
+ STAR_OFFSET_X + x * STAR_TILE_SIZE,
+ STAR_OFFSET_Y + y * STAR_TILE_SIZE,
+ STAR_TILE_SIZE, STAR_TILE_SIZE, false);
+ break;
+ }
+ ptr_tab++;
+ }
+ ptr_tab++;
+ }
+ star_display_board_info();
+ star_transition_update();
+ return 1;
+}
+
+/**
+ * Run the game.
+ */
+static int star_run_game(void)
+{
+ int move_x = 0;
+ int move_y = 0;
+ int i;
+
+ int label_offset_y;
+
+ label_offset_y = LCD_HEIGHT - char_height;
+
+ if (!star_load_level(current_level))
+ return 0;
+
+ while (true)
+ {
+ move_x = 0;
+ move_y = 0;
+
+ switch (rb->button_get(true))
+ {
+ case BUTTON_OFF:
+ return PLUGIN_OK;
+
+ case BUTTON_LEFT:
+ move_x = -1;
+ break;
+
+ case BUTTON_RIGHT:
+ move_x = 1;
+ break;
+
+ case BUTTON_UP:
+ move_y = -1;
+ break;
+
+ case BUTTON_DOWN:
+ move_y = 1;
+ break;
+
+ case BUTTON_F1:
+ if (current_level > 0)
+ {
+ current_level--;
+ star_load_level(current_level);
+ }
+ continue;
+
+ case BUTTON_F2:
+ star_load_level(current_level);
+ continue;
+
+ case BUTTON_F3:
+ if (current_level < STAR_LEVEL_COUNT - 1)
+ {
+ current_level++;
+ star_load_level(current_level);
+ }
+ continue;
+
+ case BUTTON_PLAY:
+ case BUTTON_ON:
+ if (control == STAR_CONTROL_BALL)
+ control = STAR_CONTROL_BLOCK;
+ else
+ control = STAR_CONTROL_BALL;
+ star_display_board_info();
+ continue;
+
+ default:
+ continue;
+ }
+
+ if (control == STAR_CONTROL_BALL)
+ {
+ board[ball_y][ball_x] = STAR_VOID;
+ while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID
+ || board[ball_y + move_y][ball_x + move_x] == STAR_STAR))
+
+ {
+ for (i = 0 ; i < 7 ; i++)
+ {
+ rb->lcd_bitmap(
+ ball_bmp,
+ STAR_OFFSET_X + ball_x * STAR_TILE_SIZE + move_x * i,
+ STAR_OFFSET_Y + ball_y * STAR_TILE_SIZE + move_y * i,
+ STAR_TILE_SIZE, STAR_TILE_SIZE, true);
+
+ rb->lcd_update_rect(
+ STAR_OFFSET_X + ball_x * STAR_TILE_SIZE + move_x * i,
+ STAR_OFFSET_Y + ball_y * STAR_TILE_SIZE + move_y * i,
+ STAR_TILE_SIZE, STAR_TILE_SIZE);
+ rb->sleep(STAR_SLEEP);
+ }
+ ball_x += move_x;
+ ball_y += move_y;
+
+ if (board[ball_y][ball_x] == STAR_STAR)
+ {
+ board[ball_y][ball_x] = STAR_VOID;
+ star_count--;
+
+ star_display_board_info();
+ }
+ }
+ board[ball_y][ball_x] = STAR_BALL;
+ }
+ else
+ {
+ board[block_y][block_x] = STAR_VOID;
+ while (board[block_y + move_y][block_x + move_x] == STAR_VOID)
+ {
+ for (i = 0 ; i < 7 ; i++)
+ {
+ rb->lcd_bitmap(
+ block_bmp,
+ STAR_OFFSET_X + block_x * STAR_TILE_SIZE + move_x * i,
+ STAR_OFFSET_Y + block_y * STAR_TILE_SIZE + move_y * i,
+ STAR_TILE_SIZE, STAR_TILE_SIZE, true);
+
+ rb->lcd_update_rect(
+ STAR_OFFSET_X + block_x * STAR_TILE_SIZE + move_x * i,
+ STAR_OFFSET_Y + block_y * STAR_TILE_SIZE + move_y * i,
+ STAR_TILE_SIZE, STAR_TILE_SIZE);
+
+ rb->sleep(STAR_SLEEP);
+ }
+ block_x += move_x;
+ block_y += move_y;
+ }
+ board[block_y][block_x] = STAR_BLOCK;
+ }
+
+ if (star_count == 0)
+ {
+ current_level++;
+ if (current_level == STAR_LEVEL_COUNT)
+ {
+ rb->lcd_clear_display();
+ star_display_text("Congratulation !", true);
+ rb->lcd_update();
+ return 1;
+ }
+ star_load_level(current_level);
+ }
+ }
+}
+
+/**
+ * Display the choice menu.
+ */
+static int star_menu(void)
+{
+ int move_y;
+ int menu_y = 0;
+ int i = 0;
+ bool refresh = true;
+ char anim_state = 0;
+ unsigned char *menu[4] = {"Start", "Information", "Keys", "Exit"};
+ int menu_count = sizeof(menu) / sizeof(unsigned char *);
+ int menu_offset_y;
+
+ menu_offset_y = LCD_HEIGHT - char_height * menu_count;
+
+ while (true)
+ {
+ if (refresh)
+ {
+ rb->lcd_clear_display();
+ rb->lcd_putsxy((LCD_WIDTH - char_width *
+ rb->strlen(STAR_TITLE)) / 2,
+ 0, STAR_TITLE);
+ for (i = 0 ; i < menu_count ; i++)
+ {
+ rb->lcd_putsxy(15, menu_offset_y + char_height * i, menu[i]);
+ }
+
+ rb->lcd_update();
+ refresh = false;
+ }
+
+ move_y = 0;
+ rb->lcd_bitmap(arrow_bmp[anim_arrow[(anim_state & 0x38) >> 3]],
+ 2, menu_offset_y + menu_y * char_height, 7, 8, true);
+ rb->lcd_update_rect (2, menu_offset_y + menu_y * 8, 8, 8);
+ rb->sleep(STAR_SLEEP);
+ anim_state++;
+
+ switch (rb->button_get(false))
+ {
+ case BUTTON_OFF:
+ return PLUGIN_OK;
+ case BUTTON_UP:
+ if (menu_y > 0)
+ move_y = -1;
+ break;
+ case BUTTON_DOWN:
+ if (menu_y < 3)
+ move_y = 1;
+ break;
+
+ case BUTTON_ON:
+ case BUTTON_PLAY:
+ case BUTTON_RIGHT:
+ refresh = true;
+ switch (menu_y)
+ {
+ case 0:
+ if (!star_run_game())
+ return PLUGIN_OK;
+ break;
+ case 1:
+ star_display_text(
+ "INFO\n\n"
+ "Take all \"o\" to go to the next level. "
+ "You can toggle control with the block to "
+ "use it as a mobile wall. The block cannot "
+ "take \"o\".", true);
+ break;
+ case 2:
+ star_display_text("KEYS\n\n"
+ "[ON] Toggle Ctl.\n"
+ "[OFF] Exit\n"
+ "[F1] Prev. level\n"
+ "[F2] Reset level\n"
+ "[F3] Next level", true);
+ break;
+ case 3:
+ return PLUGIN_OK;
+ }
+ break;
+
+ case SYS_USB_CONNECTED:
+ rb->usb_screen();
+ return PLUGIN_USB_CONNECTED;
+
+ default:
+ continue;
+ }
+
+ for (i = 0 ; i < char_height ; i++)
+ {
+ rb->lcd_clearrect (2, 30, 7, 4 * 8);
+ rb->lcd_bitmap(arrow_bmp[anim_arrow[(anim_state & 0x38) >> 3]],
+ 2, menu_offset_y + menu_y * 8 + move_y * i, 7, 8,
+ false);
+ rb->lcd_update_rect(2, 30, 8, 4 * 8);
+ anim_state++;
+ rb->sleep(STAR_SLEEP);
+ }
+ menu_y += move_y;
+ }
+}
+
+/**
+ * Main entry point
+ */
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+ TEST_PLUGIN_API(api);
+ (void)parameter;
+ rb = api;
+
+ /* get the size of char */
+ if (char_width == -1)
+ rb->lcd_getstringsize("a", &char_width, &char_height);
+
+ /* display choice menu */
+ return star_menu();
+}
+
+#endif