From ba371fb595affd68c823926b85718d1d613dc7d3 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Sun, 29 Jun 2003 16:33:04 +0000 Subject: Added plugin loader. Moved games, demos and the text viewer to loadable plugins. Copy your *.rock files to /.rockbox/rocks/ git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3769 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/viewer.c | 415 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 apps/plugins/viewer.c (limited to 'apps/plugins/viewer.c') diff --git a/apps/plugins/viewer.c b/apps/plugins/viewer.c new file mode 100644 index 0000000000..f8dc309a6e --- /dev/null +++ b/apps/plugins/viewer.c @@ -0,0 +1,415 @@ +/*************************************************************************** + * + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Gilles Roux + * + * 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" + +#define BUFFER_SIZE 1024 +#define OUTSIDE_BUFFER -10 +#define OUTSIDE_FILE -11 + +static int fd; +static int file_size; + +static char buffer[BUFFER_SIZE+1]; +static int buffer_pos; /* Position of the buffer in the file */ + +static char display_lines; /* number of lines on the display */ +static char display_columns; /* number of columns on the display */ +static int begin_line; /* Index of the first line displayed on the lcd */ +static int end_line; /* Index of the last line displayed on the lcd */ +static int begin_line_pos; /* Position of the first_line in the bufffer */ +static int end_line_pos; /* Position of the last_line in the buffer */ +static struct plugin_api* rb; + +/* + * Known issue: The caching algorithm will fail (display incoherent data) if + * the total space of the lines that are displayed on the screen exceeds the + * buffer size (only happens with very long lines). + */ + +static void display_line_count(void) +{ +#ifdef HAVE_LCD_BITMAP + int w,h; + rb->lcd_getstringsize("M", &w, &h); + display_lines = LCD_HEIGHT / h; + display_columns = LCD_WIDTH / w; +#else + display_lines = 2; + display_columns = 11; +#endif +} + +static int find_next_line(int pos) +{ + int i; + + if (pos==OUTSIDE_BUFFER || pos==OUTSIDE_FILE) + return pos; + + i = pos; + if (buffer_pos+i>=file_size) { + return OUTSIDE_FILE; + } + while (1) { + i++; + if (buffer_pos+i==file_size) { + return i; + } + if (i>=BUFFER_SIZE) { + return OUTSIDE_BUFFER; + } + if (buffer[i]==0) { + return i; + } + } +} + +static int find_prev_line(int pos) +{ + int i; + + if (pos==OUTSIDE_BUFFER || pos==OUTSIDE_FILE) + return pos; + + i = pos; + if (buffer_pos+i<0) { + return OUTSIDE_FILE; + } + while (1) { + i--; + if (buffer_pos+i<0) { + return i; + } + if (i<0) { + return OUTSIDE_BUFFER; + } + if (buffer[i]==0) { + return i; + } + } +} + +static void viewer_draw(int col) +{ + int i, j; + char* str; + int line_pos; + + rb->lcd_clear_display(); + + line_pos = begin_line_pos; + + for (i=0; i <= end_line - begin_line; i++) { + if (line_pos == OUTSIDE_BUFFER || + line_pos == OUTSIDE_FILE) + break; + str = buffer + line_pos + 1; + for (j=0; jlcd_puts(0, i, str); + line_pos = find_next_line(line_pos); + } +#ifdef HAVE_LCD_BITMAP + rb->lcd_update(); +#endif +} + +static void fill_buffer(int pos) +{ + int i; + int numread; + + if (pos>=file_size-BUFFER_SIZE) + pos = file_size-BUFFER_SIZE; + if (pos<0) + pos = 0; + + rb->lseek(fd, pos, SEEK_SET); + numread = rb->read(fd, buffer, BUFFER_SIZE); + + begin_line_pos -= pos - buffer_pos; + end_line_pos -= pos - buffer_pos; + buffer_pos = pos; + + buffer[numread] = 0; + for(i=0;iopen(file, O_RDONLY); + if (fd==-1) + return false; + + file_size = rb->lseek(fd, 0, SEEK_END); + + buffer_pos = 0; + begin_line = 0; + begin_line_pos = -1; + end_line = -1; + end_line_pos = -1; + fill_buffer(0); + display_line_count(); + for (i=0; iclose(fd); +} + +static void viewer_scroll_down(void) +{ + int ret; + + ret = find_next_line(end_line_pos); + switch ( ret ) { + case OUTSIDE_BUFFER: + begin_line_pos = find_next_line(begin_line_pos); + fill_buffer(begin_line_pos+buffer_pos); + end_line_pos = find_next_line(end_line_pos); + break; + + case OUTSIDE_FILE: + return; + + default: + begin_line_pos = find_next_line(begin_line_pos); + end_line_pos = ret; + break; + } + begin_line++; + end_line++; +} + +static void viewer_scroll_up(void) +{ + int ret; + + ret = find_prev_line(begin_line_pos); + switch ( ret ) { + case OUTSIDE_BUFFER: + end_line_pos = find_prev_line(end_line_pos); + fill_buffer(buffer_pos+end_line_pos-BUFFER_SIZE); + begin_line_pos = find_prev_line(begin_line_pos); + break; + + case OUTSIDE_FILE: + return; + + default: + end_line_pos = find_prev_line(end_line_pos); + begin_line_pos = ret; + break; + } + begin_line--; + end_line--; +} + +static int pagescroll(int col) +{ + bool exit = false; + int i; + + while (!exit) { + switch (rb->button_get(true)) { +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_ON | BUTTON_UP: + case BUTTON_ON | BUTTON_UP | BUTTON_REPEAT: +#else + case BUTTON_ON | BUTTON_LEFT: + case BUTTON_ON | BUTTON_LEFT | BUTTON_REPEAT: +#endif + for (i=0; isplash(HZ, 0, false, "Error"); + viewer_exit(); + return PLUGIN_OK; + } + + viewer_draw(col); + while (!exit) { + button = rb->button_get(true); + + switch ( button ) { + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_F1: + case BUTTON_OFF: +#else + case BUTTON_STOP: +#endif + viewer_exit(); + exit = true; + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_UP: + case BUTTON_UP | BUTTON_REPEAT: +#else + case BUTTON_LEFT: + case BUTTON_LEFT | BUTTON_REPEAT: +#endif + viewer_scroll_up(); + viewer_draw(col); + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_DOWN: + case BUTTON_DOWN | BUTTON_REPEAT: +#else + case BUTTON_RIGHT: + case BUTTON_RIGHT | BUTTON_REPEAT: +#endif + viewer_scroll_down(); + viewer_draw(col); + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_LEFT: + case BUTTON_LEFT | BUTTON_REPEAT: +#else + case BUTTON_MENU | BUTTON_LEFT: + case BUTTON_MENU | BUTTON_LEFT | BUTTON_REPEAT: +#endif + col--; + if (col < 0) + col = 0; + viewer_draw(col); + break; + +#ifdef HAVE_RECORDER_KEYPAD + case BUTTON_RIGHT: + case BUTTON_RIGHT | BUTTON_REPEAT: +#else + case BUTTON_MENU | BUTTON_RIGHT: + case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REPEAT: +#endif + col++; + viewer_draw(col); + break; + + case BUTTON_ON: +#ifdef HAVE_PLAYER_KEYPAD + case BUTTON_ON | BUTTON_MENU: +#endif + col = pagescroll(col); + break; + + case SYS_USB_CONNECTED: + rb->usb_screen(); + viewer_exit(); + return PLUGIN_USB_CONNECTED; + } + } + return PLUGIN_OK; +} -- cgit v1.2.3