From 1c0c861451caf00d5f8205fe71dcc79cd52dbe5b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 May 2002 12:22:24 +0000 Subject: moved from the simulator dir git-svn-id: svn://svn.rockbox.org/rockbox/trunk@614 a1c6a512-1295-4272-9138-f99709370657 --- apps/app.c | 104 ++++++++++ apps/bmp.c | 584 +++++++++++++++++++++++++++++++++++++++++++++++++++++ apps/icons.c | 50 +++++ apps/icons.h | 37 ++++ apps/menu.c | 187 +++++++++++++++++ apps/menu.h | 51 +++++ apps/screensaver.c | 129 ++++++++++++ apps/screensaver.h | 27 +++ apps/tetris.c | 362 +++++++++++++++++++++++++++++++++ 9 files changed, 1531 insertions(+) create mode 100644 apps/app.c create mode 100644 apps/bmp.c create mode 100644 apps/icons.c create mode 100644 apps/icons.h create mode 100644 apps/menu.c create mode 100644 apps/menu.h create mode 100644 apps/screensaver.c create mode 100644 apps/screensaver.h create mode 100644 apps/tetris.c diff --git a/apps/app.c b/apps/app.c new file mode 100644 index 0000000000..c5149d8171 --- /dev/null +++ b/apps/app.c @@ -0,0 +1,104 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Daniel Stenberg + * + * 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 "lcd.h" +#include "button.h" +#include "kernel.h" +#include "menu.h" + +/* Apps to include */ +#include "tree.h" + +#ifdef HAVE_LCD_BITMAP + +/*#include "screensaver.h"*/ + +/*extern void tetris(void);*/ + +void app_main(void) +{ + int key; + + menu_init(); + menu_draw(); + put_cursor_menu_top(); + + while(1) { + key = button_get(); + + if(!key) { + sleep(1); + continue; + } + + switch(key) { + case BUTTON_UP: + if(is_cursor_menu_top()){ + /* wrap around to menu bottom */ + put_cursor_menu_bottom(); + } else { + /* move up */ + move_cursor_up(); + } + break; + case BUTTON_DOWN: + if(is_cursor_menu_bottom() ){ + /* wrap around to menu top */ + put_cursor_menu_top(); + } else { + /* move down */ + move_cursor_down(); + } + break; + case BUTTON_RIGHT: + case BUTTON_PLAY: + /* Erase current display state */ + lcd_clear_display(); + + execute_menu_item(); + + /* Return to previous display state */ + lcd_clear_display(); + menu_draw(); + break; + case BUTTON_OFF: + return; + default: + break; + } + + lcd_update(); + } +} + +#else + +void app_main(void) +{ + int key; + int cursor = 0; + + lcd_puts(0,0, "Mooo!"); + lcd_puts(1,1, " Rockbox!"); + + browse_root(); + +} + +#endif diff --git a/apps/bmp.c b/apps/bmp.c new file mode 100644 index 0000000000..828f855295 --- /dev/null +++ b/apps/bmp.c @@ -0,0 +1,584 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Linus Nielsen Feltzing + * + * 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. + * + ****************************************************************************/ +/********************************************************************* + * + * Converts BMP files to Rockbox bitmap format + * + * 1999-05-03 Linus Nielsen Feltzing + * + **********************************************/ + +#include +#include +#include +#include + +#include "file.h" + +#ifdef __GNUC__ +#define STRUCT_PACKED __attribute__((packed)) +#endif + +struct Fileheader +{ + unsigned short Type; /* signature - 'BM' */ + unsigned long Size; /* file size in bytes */ + unsigned short Reserved1; /* 0 */ + unsigned short Reserved2; /* 0 */ + unsigned long OffBits; /* offset to bitmap */ + unsigned long StructSize; /* size of this struct (40) */ + unsigned long Width; /* bmap width in pixels */ + unsigned long Height; /* bmap height in pixels */ + unsigned short Planes; /* num planes - always 1 */ + unsigned short BitCount; /* bits per pixel */ + unsigned long Compression; /* compression flag */ + unsigned long SizeImage; /* image size in bytes */ + long XPelsPerMeter; /* horz resolution */ + long YPelsPerMeter; /* vert resolution */ + unsigned long ClrUsed; /* 0 -> color table size */ + unsigned long ClrImportant; /* important color count */ +} STRUCT_PACKED; + +struct RGBQUAD +{ + unsigned char rgbBlue; + unsigned char rgbGreen; + unsigned char rgbRed; + unsigned char rgbReserved; +} STRUCT_PACKED; + +static struct Fileheader fh; +static unsigned char* bmp; +static struct RGBQUAD palette[2]; /* two colors only */ + +static unsigned int bitmap_width, bitmap_height; +static unsigned char *bitmap; + +#ifdef STANDALONE +static id_str[256]; +static bool compress = false; +static bool assembly = false; +static unsigned char* converted_bmp; +static unsigned char* compressed_bmp; +static unsigned int width; +static unsigned int converted_size; +static unsigned int compressed_size; +static unsigned int rounded_width; +#endif + +#ifdef LITTLE_ENDIAN +#define readshort(x) x +#define readlong(x) x +#else + +#define readshort(x) (((x&0xff00)>>8)|((x&0x00ff)<<8)) +#define readlong(x) (((x&0xff000000)>>24)| \ + ((x&0x00ff0000)>>8) | \ + ((x&0x0000ff00)<<8) | \ + ((x&0x000000ff)<<24)) +#endif + +/********************************************************************* + * read_bmp_file() + * + * Reads a monochrome BMP file and puts the data in a 1-pixel-per-byte + * array. Returns 0 on success. + * + **********************************************/ +int read_bmp_file(char* filename, + int *get_width, /* in pixels */ + int *get_height, /* in pixels */ + char *bitmap) +{ + long PaddedWidth; + int background; + int fd = open(filename, O_RDONLY); + long size; + unsigned int row, col, byte, bit; + int l; + unsigned char *bmp; + int width; + int height; + + if(fd == -1) + { + debugf("error - can't open '%s'\n", filename); + return 1; + } + else + { + if(read(fd, &fh, sizeof(struct Fileheader)) != + sizeof(struct Fileheader)) + { + debugf("error - can't Read Fileheader Stucture\n"); + close(fd); + return 2; + } + + /* Exit if not monochrome */ + if(readshort(fh.BitCount) > 8) + { + debugf("error - Bitmap must be less than 8, got %d\n", + readshort(fh.BitCount)); + close(fd); + return 2; + } + + /* Exit if too wide */ + if(readlong(fh.Width) > 112) + { + debugf("error - Bitmap is too wide (%d pixels, max is 112)\n", + readlong(fh.Width)); + close(fd); + return 3; + } + debugf("Bitmap is %d pixels wide\n", readlong(fh.Width)); + + /* Exit if too high */ + if(readlong(fh.Height) > 64) + { + debugf("error - Bitmap is too high (%d pixels, max is 64)\n", + readlong(fh.Height)); + close(fd); + return 4; + } + debugf("Bitmap is %d pixels heigh\n", readlong(fh.Height)); + + for(l=0;l < 2;l++) + { + if(read(fd, &palette[l],sizeof(struct RGBQUAD)) != + sizeof(struct RGBQUAD)) + { + debugf("error - Can't read bitmap's color palette\n"); + close(fd); + return 5; + } + } + /* pass the other palettes */ + lseek(fd, 254*sizeof(struct RGBQUAD), SEEK_CUR); + + /* Try to guess the foreground and background colors. + We assume that the foreground color is the darkest. */ + if(((int)palette[0].rgbRed + + (int)palette[0].rgbGreen + + (int)palette[0].rgbBlue) > + ((int)palette[1].rgbRed + + (int)palette[1].rgbGreen + + (int)palette[1].rgbBlue)) + { + background = 0; + } + else + { + background = 1; + } + + /* width = readlong(fh.Width)*readshort(fh.BitCount); */ + + width = readlong(fh.Width); + + /* PaddedWidth = ((width+31)&(~0x1f))/8; */ + PaddedWidth = ((width+7)&(~0x7)); + size = PaddedWidth*readlong(fh.Height); + + bmp = (unsigned char *)malloc(size); + + if(bmp == NULL) + { + debugf("error - Out of memory\n"); + close(fd); + return 6; + } + else + { + if(read(fd, (unsigned char*)bmp,(long)size) != size) { + debugf("error - Can't read image\n"); + close(fd); + return 7; + } + } + + bitmap_height = readlong(fh.Height); + bitmap_width = readlong(fh.Width); + + *get_width = bitmap_width; + *get_height = bitmap_height; + +#if 0 + /* Now convert the bitmap into an array with 1 byte per pixel, + exactly the size of the image */ + for(row = 0;row < bitmap_height;row++) { + bit = 7; + byte = 0; + for(col = 0;col < bitmap_width;col++) { + if((bmp[(bitmap_height - row - 1) * PaddedWidth + byte] & + (1 << bit))) { + + bitmap[ (row/8) * bitmap_width + col ] |= 1<<(row&7); + } + else { + bitmap[ (row/8) * bitmap_width + col ] &= ~ 1<<(row&7); + } + if(bit) { + bit--; + } + else { + bit = 7; + byte++; + } + } + } +#else + /* Now convert the bitmap into an array with 1 byte per pixel, + exactly the size of the image */ + + for(row = 0;row < bitmap_height;row++) { + for(col = 0;col < bitmap_width;col++) { + if(bmp[(bitmap_height-1 -row) * PaddedWidth + col]) { + bitmap[ (row/8) * bitmap_width + col ] &= ~ (1<<(row&7)); + } + else { + bitmap[ (row/8) * bitmap_width + col ] |= 1<<(row&7); + } + } + } + +#endif + } + close(fd); + return 0; /* success */ +} + +#ifdef STANDALONE + +/********************************************************************* +** read_next_converted_byte() +** +** Reads the next 6-pixel chunk from the 1-byte-per-pixel array, +** padding the last byte with zeros if the size is not divisible by 6. +**********************************************/ +unsigned char read_next_converted_byte(void) +{ + unsigned char dest; + unsigned int i; + static unsigned int row = 0, col = 0; + + dest = 0; + for(i = 0;i < 6 && col < bitmap_width;i++,col++) + { + if(bitmap[row * bitmap_width + col]) + { + dest |= (unsigned char)(1 << (5-i)); + } + } + + if(col >= bitmap_width) + { + col = 0; + row++; + } + + return dest; +} + +/********************************************************************* +** convert_image() +** +** Converts the 1-byte-per-pixel array into a 6-pixel-per-byte array, +** i.e the BMP_FORMAT_VANILLA format. +**********************************************/ +void convert_image(void) +{ + int newsize; + unsigned int row, col; + + rounded_width = fh.Width/6 + ((fh.Width%6)?1:0); + newsize = rounded_width * fh.Height; + + converted_bmp = (unsigned char *)malloc(newsize); + + for(row = 0;row < fh.Height;row++) + { + for(col = 0;col < rounded_width;col++) + { + converted_bmp[row * rounded_width + col] = read_next_converted_byte(); + } + } + converted_size = rounded_width * fh.Height; +} + +#define COMPRESSED_ZEROS_AHEAD 0x40 +#define COMPRESSED_ONES_AHEAD 0x80 + +/********************************************************************* +** compress_image() +** +** Compresses the BMP_FORMAT_VANILLA format with a simple RLE +** algorithm. The output is in the BMP_FORMAT_RLE format. +**********************************************/ +void compress_image(void) +{ + unsigned int i, j, count; + unsigned int index = 0; + unsigned char val; + + compressed_bmp = (unsigned char *)malloc(converted_size); + + for(i = 0;i < converted_size;i++) + { + val = converted_bmp[i]; + + if(val == 0|| val == 0x3f) + { + count = 0; + while(count < 0x4000 && (i + count) < converted_size && + converted_bmp[i+count] == val) + { + count++; + } + if(count > 2) + { + compressed_bmp[index++] = (unsigned char) + (((val == 0)?COMPRESSED_ZEROS_AHEAD:COMPRESSED_ONES_AHEAD) | + (count >> 8)); + compressed_bmp[index++] = (unsigned char)(count & 0xff); + } + else + { + for(j = 0;j < count;j++) + { + compressed_bmp[index++] = val; + } + } + i += count - 1; + } + else + { + compressed_bmp[index++] = val; + } + } + + compressed_size = index; +} + +/********************************************************************* +** generate_c_source() +** +** Outputs a C source code with the converted/compressed bitmap in +** an array, accompanied by some #define's +**********************************************/ +void generate_c_source(char *id, BOOL compressed) +{ + FILE *f; + unsigned int i; + unsigned int size; + unsigned char *bmp; + + size = compressed?compressed_size:converted_size; + bmp = compressed?compressed_bmp:converted_bmp; + + f = stdout; + + fprintf(f, "#define %s_WIDTH %d\n", id, rounded_width * 6); + fprintf(f, "#define %s_HEIGHT %d\n", id, fh.Height); + fprintf(f, "#define %s_SIZE %d\n", id, size + 6); + if(compressed) + { + fprintf(f, "#define %s_ORIGINAL_SIZE %d\n", id, converted_size); + } + fprintf(f, "#define %s_FORMAT %s\n", id, + compressed?"BMP_FORMAT_RLE":"BMP_FORMAT_VANILLA"); + fprintf(f, "\nconst unsigned char bmpdata_%s[] = {", id); + + /* Header */ + fprintf(f, "\n %s, 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,", + compressed?"BMP_FORMAT_RLE":"BMP_FORMAT_VANILLA", + size >> 8, size & 0xff, 2, fh.Height, rounded_width * 6); + + for(i = 0;i < size;i++) + { + if(i % 10 == 0) + { + fprintf(f, "\n "); + } + fprintf(f, "0x%02x,", bmp[i]); + } + fprintf(f, "\n};"); +} + +/********************************************************************* +** generate_asm_source() +** +** Outputs an ASM source code with the converted/compressed bitmap in +** an array, the first 2 bytes describing the X and Y size +**********************************************/ +void generate_asm_source(char *id, BOOL compressed) +{ + FILE *f; + unsigned int i; + unsigned int size; + unsigned char *bmp; + + size = compressed?compressed_size:converted_size; + bmp = compressed?compressed_bmp:converted_bmp; + + f = stdout; + + fprintf(f, "bmpdata_%s:\n", id); + /* Header */ + fprintf(f, "\n db %s, %.2xh,%.2xh,%.2xh,%.2xh,%.2xh,", + compressed?"1":"0", + size >> 8, size & 0xff, 2, fh.Height, rounded_width * 6); + + for(i = 0;i < size;i++) + { + if(i % 10 == 0) + { + fprintf(f, "\n db "); + } + fprintf(f, "%.2xh,", bmp[i]); + } + fprintf(f, "\n"); +} + +void print_usage(void) +{ + printf("bmp2mt - Converts BMP files to MT Pro source code format\n"); + printf("build date: " __DATE__ "\n\n"); + printf("Usage: %s [-i ] [-c] [-a] \n" + "-i Bitmap ID (default is filename without extension)\n" + "-c Compress (BMP_FORMAT_RLE)\n" + "-f Frexx Format!!!\n" + "-a Assembly format source code\n", APPLICATION_NAME); +} + +#pragma argsused +int main(int argc, char **argv) +{ + char *bmp_filename = NULL; + char *id = NULL; + char errstr[80]; + int i; + + for(i = 1;i < argc;i++) + { + if(argv[i][0] == '-') + { + switch(argv[i][1]) + { + case 'i': /* ID */ + if(argv[i][2]) + { + id = &argv[i][2]; + } + else if(argc > i+1) + { + id = argv[i+1]; + i++; + } + else + { + print_usage(); + exit(1); + } + break; + + case 'c': /* Compressed */ + compress = true; + break; + + case 'a': /* Assembly */ + assembly = true; + break; + + default: + print_usage(); + exit(1); + break; + } + } + else + { + if(!bmp_filename) + { + bmp_filename = argv[i]; + } + else + { + print_usage(); + exit(1); + } + } + } + + if(!bmp_filename) + { + print_usage(); + exit(1); + } + + if(!id) + { + id = strdup(bmp_filename); + + for(i = 0;id[i];i++) + { + if(id[i] == ' ') + { + id[i] = '_'; + } + else if(id[i] == '.') + { + id[i] = '\0'; + break; + } + else + { + id[i] = (char)toupper(id[i]); + } + } + } + + read_bmp_file(bmp_filename); + convert_image(); + if(fh.Width % 6) + { + + sprintf(errstr, "warning - width is not divisible by 6 (%d), " + "padding with zeros to %d\n", fh.Width, rounded_width*6); + print_error(errstr, 0); + } + + if(compress) + { + compress_image(); + } + + if(assembly) + { + generate_asm_source(id, compress); + } + else + { + generate_c_source(id, compress); + } + return 0; +} + +#endif diff --git a/apps/icons.c b/apps/icons.c new file mode 100644 index 0000000000..6627c7d06e --- /dev/null +++ b/apps/icons.c @@ -0,0 +1,50 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Robert E. Hak + * + * 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 + +#include "icons.h" + +#ifdef HAVE_LCD_BITMAP + +unsigned char bitmap_icons_6x8[LastIcon][6] = +{ + /* Box_Filled */ + { 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f }, + /* Box_Empty */ + { 0x00, 0x7f, 0x41, 0x41, 0x41, 0x7f }, + /* Slider_Horizontal */ + { 0x00, 0x3e, 0x7f, 0x63, 0x7f, 0x3e }, + /* File */ + { 0x60, 0x7f, 0x03, 0x63, 0x7f, 0x00 }, + /* Folder */ + { 0x00, 0x7e, 0x41, 0x41, 0x42, 0x7e }, + /* Directory */ + { 0x3e, 0x26, 0x26, 0x24, 0x3c, 0x00 }, + /* Playlist */ + { 0x55, 0x00, 0x55, 0x55, 0x55, 0x00 }, + /* Repeat */ + { 0x39, 0x43, 0x47, 0x71, 0x61, 0x4e }, + /* Selected */ + { 0x00, 0x1c, 0x3e, 0x3e, 0x3e, 0x1c }, + /* Selector */ + { 0x00, 0x7f, 0x3e, 0x1c, 0x08, 0x00 }, +}; + + +#endif diff --git a/apps/icons.h b/apps/icons.h new file mode 100644 index 0000000000..08e4a7e1e8 --- /dev/null +++ b/apps/icons.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Robert E. Hak + * + * 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 + +/* + * Icons of size 6x8 pixels + */ + +#ifdef HAVE_LCD_BITMAP + +enum icons_6x8 { + Box_Filled, Box_Empty, Slider_Horizontal, File, + Folder, Directory, Playlist, Repeat, + Selected, Selector, LastIcon +}; + +extern unsigned char bitmap_icons_6x8[LastIcon][6]; +extern icons_6x8; + +#endif /* End HAVE_LCD_BITMAP */ + diff --git a/apps/menu.c b/apps/menu.c new file mode 100644 index 0000000000..5c8356c93a --- /dev/null +++ b/apps/menu.c @@ -0,0 +1,187 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Robert E. Hak + * + * 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 "lcd.h" +#include "menu.h" + +#include "tree.h" + +#ifdef HAVE_LCD_BITMAP + +#include "screensaver.h" +extern void tetris(void); + + +#define MENU_ITEM_FONT 0 +#define MENU_ITEM_Y_LOC 6 +#define MENU_LINE_HEIGHT 8 + +enum Main_Menu_Ids { + Tetris, Screen_Saver, Browse, Last_Id +}; + +struct main_menu_items items[] = { + { Tetris, "Tetris", tetris }, + { Screen_Saver, "Screen Saver", screensaver }, + { Browse, "Browse", browse_root }, +}; + +/* Global values for menuing */ +int menu_top; +int menu_bottom; +int menu_line_height; +int cursor; + +int get_line_height(void) +{ + return menu_line_height; +} + +int is_cursor_menu_top(void) +{ + return ((cursor == menu_top) ? 1 : 0); +} + +int is_cursor_menu_bottom(void) +{ + return ((cursor == menu_bottom) ? 1 : 0); +} + +void put_cursor_menu_top(void) +{ + put_cursor(menu_top); +} + +void put_cursor_menu_bottom(void) +{ + put_cursor(menu_bottom); +} + +void move_cursor_up(void) +{ + put_cursor(cursor-1); +} + +void move_cursor_down(void) +{ + put_cursor(cursor+1); +} + +void redraw_cursor(void) +{ + lcd_putsxy(0, cursor*menu_line_height, "-", 0); +} + +/* + * Move the cursor to a particular id, + * current: where it is now + * target: where you want it to be + */ +void put_cursor(int target) +{ + lcd_putsxy(0, cursor*menu_line_height, " ",0); + cursor = target; + lcd_putsxy(0, cursor*menu_line_height, "-",0); +} + +/* We call the function pointer related to the current cursor position */ +void execute_menu_item(void) +{ + /* call the proper function for this line */ + items[cursor].function(); +} + +void add_menu_item(int location, char *string) +{ + lcd_putsxy(MENU_ITEM_Y_LOC, MENU_LINE_HEIGHT*location, string, + MENU_ITEM_FONT); + if (location < menu_top) + menu_top = location; + if (location > menu_bottom) + menu_bottom = location; +} + +void show_logo(void) +{ + unsigned char buffer[112 * 8]; + + int failure; + int width=0; + int height=0; + + failure = read_bmp_file("/rockbox112.bmp", &width, &height, buffer); + + debugf("read_bmp_file() returned %d, width %d height %d\n", + failure, width, height); + + if(!failure) { + int i; + int eline; + for(i=0, eline=0; i< height; i+=8, eline++) { + int x,y; + + /* the bitmap function doesn't work with full-height bitmaps + so we "stripe" the logo output */ + + lcd_bitmap(&buffer[eline*width], 0, 24+i, width, + (height-i)>8?8:height-i, false); + +#if 0 + /* for screen output debugging */ + for(y=0; y<8 && (i+y < height); y++) { + for(x=0; x < width; x++) { + + if(buffer[eline*width + x] & (1< ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Robert E. Hak + * + * 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. + * + ****************************************************************************/ + +#ifndef __MENU_H__ +#define __MENU_H__ + +struct main_menu_items { + int menu_id; + const char *menu_desc; + void (*function) (void); +}; + +int get_line_height(void); + +/* Cursor calls */ +void put_cursor(int target); +void put_cursor_menu_top(void); +void put_cursor_menu_bottom(void); +void move_cursor_up(void); +void move_cursor_down(void); +int is_cursor_menu_top(void); +int is_cursor_menu_bottom(void); + +/* Menu calls */ +void add_menu_item(int location, char *string); +void menu_init(void); +void menu_draw(void); +void execute_menu_item(void); + +#endif /* End __MENU_H__ */ + + + + + diff --git a/apps/screensaver.c b/apps/screensaver.c new file mode 100644 index 0000000000..b8144478e2 --- /dev/null +++ b/apps/screensaver.c @@ -0,0 +1,129 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Robert E. Hak (rhak at ramapo.edu) + * + * 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. + * + ****************************************************************************/ + +#ifdef HAVE_LCD_BITMAP + +#include "screensaver.h" +#include "lcd.h" +#include "button.h" +#include "kernel.h" + +#ifdef SIMULATOR +#include +#include +#endif + +#define SS_TITLE "Boxes" +#define SS_TITLE_FONT 2 + +void ss_loop(void) +{ + int b; + int x2 = LCD_WIDTH/2; + int y2 = LCD_HEIGHT/2; + int x = LCD_WIDTH/2; + int y = LCD_HEIGHT/2; + int i = 0; + int center = 0; + int factor = 0; + int offset = 0; + + if (LCD_HEIGHT < LCD_WIDTH) + center = LCD_HEIGHT/2; + else + center = LCD_WIDTH/2; + + i = center+1; + while(1) + { + /* Grow */ + if ( i < 0 ) { + factor = 1; + i = 1; + } + + /* Shrink */ + if (i >= center) { + factor = -1; + i = center; + } + + offset=i*factor; + + b = button_get(); + if ( b & BUTTON_OFF ) + return; + + lcd_clear_display(); + lcd_drawrect(x-offset, y-offset, x2+offset, y2+offset); + lcd_update(); + + i+=factor; + + sleep(10); + } +} + + +void screensaver(void) +{ + int w, h; + char *off = "[Off] to stop"; + int len = strlen(SS_TITLE); + + lcd_getfontsize(SS_TITLE_FONT, &w, &h); + + /* Get horizontel centering for text */ + len *= w; + if (len%2 != 0) + len = ((len+1)/2)+(w/2); + else + len /= 2; + + if (h%2 != 0) + h = (h/2)+1; + else + h /= 2; + + lcd_clear_display(); + lcd_putsxy(LCD_WIDTH/2-len, (LCD_HEIGHT/2)-h, SS_TITLE, SS_TITLE_FONT); + + len = strlen(off); + lcd_getfontsize(0, &w, &h); + + /* Get horizontel centering for text */ + len *= w; + if (len%2 != 0) + len = ((len+1)/2)+(w/2); + else + len /= 2; + + if (h%2 != 0) + h = (h/2)+1; + else + h /= 2; + + lcd_putsxy(LCD_WIDTH/2-len, LCD_HEIGHT-(2*h), off,0); + + lcd_update(); + sleep(150); + ss_loop(); +} + +#endif diff --git a/apps/screensaver.h b/apps/screensaver.h new file mode 100644 index 0000000000..5c67b83b56 --- /dev/null +++ b/apps/screensaver.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Robert E. Hak + * + * 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. + * + ****************************************************************************/ + +#ifndef __SCREEN_SAVER_H__ +#define __SCREEN_SAVER_H__ + +void ss_loop(void); +void screensaver(void); + +#endif /*__SCREEN_SAVER_H__ */ + diff --git a/apps/tetris.c b/apps/tetris.c new file mode 100644 index 0000000000..24090eb67e --- /dev/null +++ b/apps/tetris.c @@ -0,0 +1,362 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 1999 Mattis Wadman (nappe@sudac.org) + * + * Heavily modified for embedded use by Björn Stenberg (bjorn@haxx.se) + * + * 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. + * + ****************************************************************************/ + +#ifdef HAVE_LCD_BITMAP +#include +#include "lcd.h" +#include "button.h" +#include "kernel.h" + +#ifdef SIMULATOR +#include +#endif + +#define TETRIS_TITLE "Tetris!" +#define TETRIS_TITLE_FONT 2 +#define TETRIS_TITLE_XLOC 10 +#define TETRIS_TITLE_YLOC 32 + +int start_x = 1; +int start_y = 1; +int max_x = 14; +int max_y = 24; +int current_x = 0; +int current_y = 0; +int current_f = 0; +int current_b = 0; +int level = 0; +short lines = 0; +int score = 0; +int next_b = 0; +int next_f = 0; +char virtual[LCD_WIDTH*LCD_HEIGHT]; +short level_speeds[10] = {1000,900,800,700,600,500,400,300,250,200}; +int blocks = 7; +int block_frames[7] = {1,2,2,2,4,4,4}; + +/* + block_data is built up the following way + + first array index specifies the block number + second array index specifies the rotation of the block + third array index specifies: + 0: x-coordinates of pixels + 1: y-coordinates of pixels + fourth array index specifies the coordinate of a pixel + + each block consists of four pixels whose relative coordinates are given + with block_data +*/ + +int block_data[7][4][2][4] = +{ + { + {{0,1,0,1},{0,0,1,1}} + }, + { + {{0,1,1,2},{1,1,0,0}}, + {{0,0,1,1},{0,1,1,2}} + }, + { + {{0,1,1,2},{0,0,1,1}}, + {{1,1,0,0},{0,1,1,2}} + }, + { + {{1,1,1,1},{0,1,2,3}}, + {{0,1,2,3},{2,2,2,2}} + }, + { + {{1,1,1,2},{2,1,0,0}}, + {{0,1,2,2},{1,1,1,2}}, + {{0,1,1,1},{2,2,1,0}}, + {{0,0,1,2},{0,1,1,1}} + }, + { + {{0,1,1,1},{0,0,1,2}}, + {{0,1,2,2},{1,1,1,0}}, + {{1,1,1,2},{0,1,2,2}}, + {{0,0,1,2},{2,1,1,1}} + }, + { + {{1,0,1,2},{0,1,1,1}}, + {{2,1,1,1},{1,0,1,2}}, + {{1,0,1,2},{2,1,1,1}}, + {{0,1,1,1},{1,0,1,2}} + } +}; + +/* not even pseudo random :) */ +int t_rand(int range) +{ + static int count; + count++; + return count % range; +} + +void draw_frame(int fstart_x,int fstop_x,int fstart_y,int fstop_y) +{ + lcd_drawline(fstart_x, fstart_y, fstop_x, fstart_y); + lcd_drawline(fstart_x, fstop_y, fstop_x, fstop_y); + + lcd_drawline(fstart_x, fstart_y, fstart_x, fstop_y); + lcd_drawline(fstop_x, fstart_y, fstop_x, fstop_y); +} + +void draw_block(int x,int y,int block,int frame,bool clear) +{ + int i; + for(i=0;i < 4;i++) { + if (clear) + lcd_clearpixel(start_x+x+block_data[block][frame][0][i], + start_y+y+block_data[block][frame][1][i]); + else + lcd_drawpixel(start_x+x+block_data[block][frame][0][i], + start_y+y+block_data[block][frame][1][i]); + } +} + +void to_virtual() +{ + int i; + for(i=0;i < 4;i++) + *(virtual+ + ((current_y+block_data[current_b][current_f][1][i])*max_x)+ + (current_x+block_data[current_b][current_f][0][i])) = current_b+1; +} + +bool gameover() +{ + int i; + int frame, block, y, x; + + x = current_x; + y = current_y; + block = current_b; + frame = current_f; + + for(i=0;i < 4; i++){ + /* Do we have blocks touching? */ + if(*(virtual+((y+block_data[block][frame][1][i])*max_x)+x+ + block_data[block][frame][0][i]) != 0) + { + /* Are we at the top of the frame? */ + if(y+block_data[block][frame][1][i] < start_y) + { + /* Game over ;) */ + return true; + } + } + } + return false; +} + +bool valid_position(int x,int y,int block,int frame) +{ + int i; + for(i=0;i < 4;i++) + if( (*(virtual+((y+block_data[block][frame][1][i])*max_x)+x+ + block_data[block][frame][0][i]) != 0) || + (x+block_data[block][frame][0][i] < 0) || + (x+block_data[block][frame][0][i] > max_x-1) || + (y+block_data[block][frame][1][i] < 0) || + (y+block_data[block][frame][1][i] > max_y-1)) + return false; + return true; +} + +void from_virtual() +{ + int x,y; + for(y=0;y < max_y;y++) + for(x=0;x < max_x;x++) + if(*(virtual+(y*max_x)+x)) + lcd_drawpixel(start_x+x,start_y+y); + else + lcd_clearpixel(start_x+x,start_y+y); +} + +void move_block(int x,int y,int f) +{ + int last_frame = current_f; + if(f != 0) + { + current_f += f; + if(current_f > block_frames[current_b]-1) + current_f = 0; + if(current_f < 0) + current_f = block_frames[current_b]-1; + } + if(valid_position(current_x+x,current_y+y,current_b,current_f)) + { + draw_block(current_x,current_y,current_b,last_frame,true); + current_x += x; + current_y += y; + draw_block(current_x,current_y,current_b,current_f,false); + lcd_update(); + } + else + current_f = last_frame; +} + +void new_block() +{ + current_b = next_b; + current_f = next_f; + current_x = (int)((max_x)/2)-1; + current_y = 0; + next_b = t_rand(blocks); + next_f = t_rand(block_frames[next_b]); + draw_block(max_x+2,start_y-1,current_b,current_f,true); + draw_block(max_x+2,start_y-1,next_b,next_f,false); + if(!valid_position(current_x,current_y,current_b,current_f)) + { + draw_block(current_x,current_y,current_b,current_f,false); + lcd_update(); + } + else + draw_block(current_x,current_y,current_b,current_f,false); +} + +int check_lines() +{ + int x,y,i; + bool line; + int lines = 0; + for(y=0;y < max_y;y++) + { + line = true; + for(x=0;x < max_x;x++) + if(virtual[y*max_x+x] == 0) + line = false; + if(line) + { + lines++; + for(i=y;i > 1;i--) + for (x=0;x 9) + level = 9; + from_virtual(); + score += l*l; + } + new_block(); + move_block(0,0,0); + } + else + move_block(0,1,0); +} + +void game_loop(void) +{ + while(1) + { + int b=0; + int count = 0; + /* while(count*20 < level_speeds[level]) */ + { + b = button_get(); + if ( b & BUTTON_OFF ) + return; /* get out of here */ + + if ( b & BUTTON_LEFT ) { + move_block(-1,0,0); + } + if ( b & BUTTON_RIGHT ) { + move_block(1,0,0); + } + if ( b & BUTTON_UP ) { + move_block(0,0,1); + } + if ( b & BUTTON_DOWN ) { + move_down(); + } + count++; + sleep(10); + } + if(gameover()) { + int w, h; + + lcd_getfontsize(TETRIS_TITLE_FONT, &w, &h); + lcd_clearrect(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, + TETRIS_TITLE_XLOC+(w*sizeof(TETRIS_TITLE)), + TETRIS_TITLE_YLOC-h); + lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, "You lose!", + TETRIS_TITLE_FONT); + lcd_update(); + sleep(2); + return; + } + move_down(); + } +} + +void init_tetris() +{ + memset(&virtual, 0, sizeof(virtual)); + start_x = 1; + start_y = 1; + max_x = 14; + max_y = 24; + current_x = 0; + current_y = 0; + current_f = 0; + current_b = 0; + level = 0; + lines = 0; + score = 0; + next_b = 0; + next_f = 0; +} + +void tetris(void) +{ + init_tetris(); + + draw_frame(start_x-1,start_x+max_x,start_y-1,start_y+max_y); + lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, TETRIS_TITLE, + TETRIS_TITLE_FONT); + lcd_update(); + + next_b = t_rand(blocks); + next_f = t_rand(block_frames[next_b]); + new_block(); + game_loop(); +} + +#endif -- cgit v1.2.3