diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES index 046eb8a5c2..709c5be93c 100644 --- a/apps/plugins/CATEGORIES +++ b/apps/plugins/CATEGORIES @@ -1,3 +1,4 @@ +matrix,demos alpine_cdc,apps battery_bench,apps blackjack,games diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index ebe4aa8b03..609afb2b97 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES @@ -44,6 +44,7 @@ disktidy.c flipit.c #ifdef HAVE_LCD_BITMAP /* Not for the Player */ +matrix.c maze.c mazezam.c text_editor.c diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES index e6e01036cb..467ff1df76 100644 --- a/apps/plugins/bitmaps/native/SOURCES +++ b/apps/plugins/bitmaps/native/SOURCES @@ -411,6 +411,9 @@ solitaire_suitsi.13x52x1.bmp /* Star */ #ifdef HAVE_LCD_COLOR +/* matrix */ +matrix_bold.bmp +matrix_normal.bmp #if LCD_WIDTH >= 320 && LCD_HEIGHT >= 188 star_tiles.20x20.bmp #elif LCD_WIDTH >= 240 && LCD_HEIGHT >= 143 diff --git a/apps/plugins/bitmaps/native/matrix_bold.bmp b/apps/plugins/bitmaps/native/matrix_bold.bmp new file mode 100755 index 0000000000..c9a415c3c3 Binary files /dev/null and b/apps/plugins/bitmaps/native/matrix_bold.bmp differ diff --git a/apps/plugins/bitmaps/native/matrix_normal.bmp b/apps/plugins/bitmaps/native/matrix_normal.bmp new file mode 100755 index 0000000000..e6e84c4bd7 Binary files /dev/null and b/apps/plugins/bitmaps/native/matrix_normal.bmp differ diff --git a/apps/plugins/matrix.c b/apps/plugins/matrix.c new file mode 100644 index 0000000000..4253b5dd0c --- /dev/null +++ b/apps/plugins/matrix.c @@ -0,0 +1,301 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 1999 Chris Allegretta + * Copyright (C) 2005 Alastair S - ported to podzilla + * Copyright (C) 2005 Jonas Häggqvist - ported to rockbox + * + * + * 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. + * + ****************************************************************************/ + +/* + * TODO: + * - The font is a bit large, create smaller one + * - For colour/greyscale displays, the font from the xscreensaver xmatrix + * should be converted and used + * BUGS: + * - The animation "dies" after a few seconds, not sure why. Works in sim. + * Symtom Fixed Oct 2007 GRaTT (Gerritt Gonzales) + */ + + +#include "plugin.h" +PLUGIN_HEADER + +/* Images */ +#define MAXCHARS 27 - 1 +extern const fb_data matrix_bold[]; +extern const fb_data matrix_normal[]; +#define COL_W 14 +#define COL_H 15 + +#define COLS LCD_WIDTH/COL_W +#define ROWS LCD_HEIGHT/COL_H + +#define LEFTMARGIN (LCD_WIDTH-(COLS*COL_W))/2 +#define TOPMARGIN (LCD_HEIGHT-(ROWS*COL_H))/2 + +#if (CONFIG_KEYPAD == IPOD_4G_PAD) +#define MATRIX_EXIT BUTTON_MENU +#define MATRIX_SLEEP_MORE BUTTON_SCROLL_BACK|BUTTON_REPEAT +#define MATRIX_SLEEP_LESS BUTTON_SCROLL_FWD|BUTTON_REPEAT +#define MATRIX_PAUSE BUTTON_PLAY +#elif (CONFIG_KEYPAD == IRIVER_H300_PAD) +#define MATRIX_EXIT BUTTON_OFF +#define MATRIX_SLEEP_MORE BUTTON_UP +#define MATRIX_SLEEP_LESS BUTTON_DOWN +#define MATRIX_PAUSE BUTTON_SELECT +#elif (CONFIG_KEYPAD == IRIVER_H10_PAD) +#define MATRIX_EXIT BUTTON_POWER +#define MATRIX_SLEEP_MORE BUTTON_SCROLL_UP|BUTTON_REPEAT +#define MATRIX_SLEEP_LESS BUTTON_SCROLL_DOWN|BUTTON_REPEAT +#define MATRIX_PAUSE BUTTON_PLAY +#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) +#define MATRIX_EXIT BUTTON_POWER +#define MATRIX_SLEEP_MORE BUTTON_UP +#define MATRIX_SLEEP_LESS BUTTON_DOWN +#define MATRIX_PAUSE BUTTON_PLAY +#elif (CONFIG_KEYPAD == GIGABEAT_PAD) +#define MATRIX_EXIT BUTTON_A +#define MATRIX_SLEEP_MORE BUTTON_UP +#define MATRIX_SLEEP_LESS BUTTON_DOWN +#define MATRIX_PAUSE BUTTON_SELECT +#elif CONFIG_KEYPAD == SANSA_E200_PAD +#define MATRIX_EXIT BUTTON_POWER +#define MATRIX_SLEEP_MORE BUTTON_SCROLL_UP|BUTTON_REPEAT +#define MATRIX_SLEEP_LESS BUTTON_SCROLL_DOWN|BUTTON_REPEAT +#define MATRIX_PAUSE BUTTON_SELECT +#elif CONFIG_KEYPAD == SANSA_C200_PAD +#define MATRIX_EXIT BUTTON_POWER +#define MATRIX_SLEEP_MORE BUTTON_UP +#define MATRIX_SLEEP_LESS BUTTON_DOWN +#define MATRIX_PAUSE BUTTON_SELECT +#else +#error Unsupported keypad +#endif + +#define SLEEP HZ/50 + +/* Codec api pointer */ +static struct plugin_api* rb; + +/* Each position is of this type */ +typedef struct cmatrix { + int val; + int bold; +} cmatrix; + +/* The matrix - who'd have guessed it was just a few hundred bytes? */ +static cmatrix matrix[ROWS][COLS]; +static int length[COLS]; +static int spaces[COLS]; +static int updates[COLS]; + +static void matrix_init(void) { + int i,j; + + /* Seed rand */ + rb->srand(*rb->current_tick); + + /* Make the matrix */ + for (i = 0; i <= ROWS; i++) { + for (j = 0; j <= COLS - 1; j++ ) { + matrix[i][j].val = -1; + matrix[i][j].bold = 0; + } + } + + for (j = 0; j <= COLS - 1; j++) { + /* Set up spaces[] array of how many spaces to skip */ + spaces[j] = rb->rand() % ROWS + 1; + + /* And length of the stream */ + length[j] = rb->rand() % (ROWS - 3) + 3; + + /* Sentinel value for creation of new objects */ + matrix[1][j].val = 129; + + /* And set updates[] array for update speed. */ + updates[j] = rb->rand() % 3 + 1; + } +} + +static void matrix_blit_char(const int row, const int col, int cha) +{ + if (cha == 129 || cha == 2 || cha > MAXCHARS) + cha = 0; + + if (matrix[row][col].bold == 1) { + rb->lcd_bitmap_part(matrix_bold, cha*COL_W, 0, 392, + col*COL_W + LEFTMARGIN, row*COL_H + TOPMARGIN, COL_W, COL_H); + } + else { + rb->lcd_bitmap_part(matrix_normal, cha*COL_W, 0, 392, + col*COL_W + LEFTMARGIN, row*COL_H + TOPMARGIN, COL_W, COL_H); + } +} + +static void matrix_loop(void) +{ + int i, j = 0, y, z, firstcoldone = 0; + static int count = 0; + int randomness = 6; + + count++; + if (count > 4) + count = 1; + + for (j = 0; j <= COLS - 1; j++) { + if (count > updates[j]) { + /* New style scrolling */ + if (matrix[0][j].val == -1 && matrix[1][j].val == 129 + && spaces[j] > 0) { + matrix[0][j].val = -1; + spaces[j]--; + } else if (matrix[0][j].val == -1 && matrix[1][j].val == 129){ + length[j] = rb->rand() % (ROWS - 3) + 3; + matrix[0][j].val = rb->rand() % (MAXCHARS-1) + 1; + if (rb->rand() % 2 == 1) + matrix[0][j].bold = 2; + spaces[j] = rb->rand() % ROWS + 1; + } + i = 0; + y = 0; + firstcoldone = 0; + while (i <= ROWS) { + /* Skip over spaces */ + /* this is whear the characters were disappearing */ +/* + while (i <= ROWS && (matrix[i][j].val == 129 || + matrix[i][j].val == -1)) + i++; +*/ + /* A little more random now for spaces */ + if (rb->rand() % randomness == 1){ + while (i <= ROWS && (matrix[i][j].val == 129 || + matrix[i][j].val == -1)){ + i++; + randomness--; + if(randomness <=1) + randomness = 6;} + }else{ + randomness++; + if(randomness >6) + randomness = 6; + } + + + if (i > ROWS) + break; + + /* Go to the head of this collumn */ + z = i; + y = 0; + while (i <= ROWS && (matrix[i][j].val != 129 && + matrix[i][j].val != -1)) { + i++; + y++; + } + + if (i > ROWS) { + matrix[z][j].val = 129; + matrix[ROWS][j].bold = 1; + matrix_blit_char(z - 1, j, matrix[z][j].val); + continue; + } + + matrix[i][j].val = rb->rand() % (MAXCHARS-1) + 1; + + if (matrix[i - 1][j].bold == 2) { + matrix[i - 1][j].bold = 1; + matrix[i][j].bold = 2; + } + + /* If we're at the top of the collumn and it's reached its + * full length (about to start moving down), we do this + * to get it moving. This is also how we keep segments + * not already growing from growing accidentally => + */ + if (y > length[j] || firstcoldone) { + matrix[z][j].val = 129; + matrix[0][j].val = -1; + } + firstcoldone = 1; + i++; + } + for (i = 1; i <= ROWS; i++) { + if (matrix[i][j].val == 0 || matrix[i][j].bold == 2) { + if (matrix[i][j].val == 0) + matrix_blit_char(i - 1, j, 20); + else + matrix_blit_char(i - 1, j, matrix[i][j].val); + } else { + if (matrix[i][j].val == 1) + matrix_blit_char(i - 1, j, 2); + else if (matrix[i][j].val == -1) + matrix_blit_char(i - 1, j, 129); + else + matrix_blit_char(i - 1, j, matrix[i][j].val); + } + } + } + } +} + +enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { + int button; + int sleep = SLEEP; + bool frozen = false; + + (void)parameter; + rb = api; + + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_backdrop(NULL); + rb->lcd_clear_display(); + matrix_init(); + + while (1) { + if (!frozen) { + matrix_loop(); + rb->lcd_update(); + rb->sleep(sleep); + } + button = rb->button_get(false); + switch(button) { + case MATRIX_PAUSE: + frozen = !frozen; + break; + case MATRIX_EXIT: + return PLUGIN_OK; + break; + case MATRIX_SLEEP_MORE: + /* Sleep longer */ + sleep += SLEEP; + break; + case MATRIX_SLEEP_LESS: + /* Sleep less */ + sleep -= SLEEP; + if (sleep < 0) sleep = 0; + break; + default: + if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { + return PLUGIN_USB_CONNECTED; + } + break; + } + } + return PLUGIN_OK; +} diff --git a/docs/CREDITS b/docs/CREDITS index 50ccd6a2c5..4e5536e6a8 100644 --- a/docs/CREDITS +++ b/docs/CREDITS @@ -348,6 +348,9 @@ James Espinoza Franz Rühmland Jordan Anderson Maurus Cuelenaere +Chris Allegretta +Alastair S +Gerritt Gonzales The libmad team The wavpack team