/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: etchasketch.c,v 1.0 2004/08/19 00:00:00 zeekoe Exp $ * * Copyright (C) 2004 Ronald Teune * * 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. * ****************************************************************************/ /* used code from: helloworld.c, snake.c, keyboard.c, as examples and lImbus, * LinusN, midk, BlueChip, amiconn and all the nice people i forget on IRC for * their help, during the completion of this masterpiece */ #include "plugin.h" static struct plugin_api* rb; /* used for saving to disk */ static unsigned char buf[112*8]; static unsigned char buf2[112*8]; static char dummy[2] = {0, 0}; char* paramfile; /* x/y positions */ int current_x, current_y; int last_x, last_y; /* misc bools */ bool done; bool drawing = true; bool went_up, went_down, went_left, went_right; /* draw the "cursor" */ void showpix(void) { rb->lcd_drawpixel(current_x, current_y); /* draw the pixel */ if(!drawing) rb->lcd_clearpixel(last_x, last_y); rb->lcd_update(); } /* used for saving to disk */ static unsigned char bmpheader[] = { 0x42, 0x4d, 0x3e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xee, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* saves a shot to disk */ void screen_dump(void) { int f; int i, shift; int x, y; char filename[MAX_PATH]; struct tm *tm = rb->get_time(); i = 0; for(y = 0;y < LCD_HEIGHT/8;y++) { for(x = 0;x < LCD_WIDTH;x++) { buf[i++] = rb->lcd_framebuffer[y * 112 + x]; } } rb->memset(buf2, 0, sizeof(buf2)); for(y = 0;y < 64;y++) { shift = y & 7; for(x = 0;x < 112/8;x++) { for(i = 0;i < 8;i++) { buf2[y*112/8+x] |= ((buf[y/8*112+x*8+i] >> shift) & 0x01) << (7-i); } } } rb->snprintf(filename, MAX_PATH, "/etch %04d-%02d-%02d %02d-%02d-%02d.bmp", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); f = rb->creat(filename, O_WRONLY); if(f >= 0) { rb->write(f, bmpheader, sizeof(bmpheader)); for(i = 63;i >= 0;i--) { rb->write(f, &buf2[i*14], 14); rb->write(f, dummy, 2); } rb->close(f); } } void screen_dump_native(void) { int f; int i; int x, y; char filename[MAX_PATH]; struct tm *tm = rb->get_time(); i = 0; for(y = 0;y < LCD_HEIGHT/8;y++) { for(x = 0;x < LCD_WIDTH;x++) { buf[i++] = rb->lcd_framebuffer[y * 112 + x]; } } rb->snprintf(filename, MAX_PATH, "/etch %04d-%02d-%02d %02d-%02d-%02d.etch", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); f = rb->creat(filename, O_WRONLY); if(f >= 0) { rb->write(f, &buf[0], 112*8); /* &buf[i*16], 16 [it was i*14,14] */ rb->close(f); } } /* reads the file */ void read_file(char* readfilename) { int f; f = rb->open(readfilename, O_RDONLY); if (f >= 0) { int numread = rb->read(f, rb->lcd_framebuffer, 112*8); rb->lcd_update(); if (!numread) { rb->splash(HZ*2, true, "file cannot be read (like this would ever happen...)"); } } else { rb->splash(HZ*2, true, "open file error"); } } /* shows info at startup */ void info(void) { done = false; while(!done) { rb->lcd_puts(3, 0, "Etch-A-Sketch"); rb->lcd_puts(0, 2, "[UP/DN/FF/RW] move"); rb->lcd_puts(0, 3, "[PLAY] toggle draw"); rb->lcd_puts(0, 4, "[F1] clear drawing"); rb->lcd_puts(0, 5, "[F2] export to bmp"); rb->lcd_puts(0, 6, "[F3] save to disk"); rb->lcd_puts(0, 7, "*PLAY* to start..."); rb->lcd_update(); switch(rb->button_get_w_tmo(HZ/4)) { case BUTTON_PLAY: done = true; break; case BUTTON_OFF: done = true; break; } } } /* runs the plugin */ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { TEST_PLUGIN_API(api); paramfile = (char*)parameter; /* the jpeg viewer did something like this */ rb = api; rb->lcd_setfont(FONT_SYSFIXED); /* assign initial values */ current_x=56; current_y=32; if (paramfile) { read_file(paramfile); } else { info(); rb->lcd_clear_display(); } showpix(); while(!PLUGIN_OK) { if(went_up) { last_x = current_x; last_y = current_y + 1; } else if(went_down) { last_x = current_x; last_y = current_y - 1; } else if(went_left) { last_x = current_x + 1; last_y = current_y; } else { last_x = current_x - 1; last_y = current_y; } showpix(); switch (rb->button_get_w_tmo(HZ/25)) { case BUTTON_UP: case BUTTON_UP | BUTTON_REPEAT: if(current_y > 0) { current_y--; went_up = true; went_down=went_left=went_right = false; } break; case BUTTON_DOWN: case BUTTON_DOWN | BUTTON_REPEAT: if(current_y < 63) { current_y++; went_down = true; went_left=went_right=went_up = false; } break; case BUTTON_LEFT: case BUTTON_LEFT | BUTTON_REPEAT: if(current_x > 0) { current_x--; went_left = true; went_up=went_down=went_right = false; } break; case BUTTON_RIGHT: case BUTTON_RIGHT | BUTTON_REPEAT: if(current_x < 111) { current_x++; went_right = true; went_up=went_down=went_left = false; } break; case BUTTON_PLAY: drawing = !drawing; break; case BUTTON_F1: rb->lcd_clear_display(); rb->lcd_update(); break; case BUTTON_F2: screen_dump(); break; case BUTTON_F3: screen_dump_native(); break; case BUTTON_OFF: return PLUGIN_OK; break; case SYS_USB_CONNECTED: rb->usb_screen(); return PLUGIN_USB_CONNECTED; break; } } }