#include "plugin.h" PLUGIN_HEADER static struct plugin_api* rb; #include "eval.c" struct point { int x; int y; }; struct plot_conf { int x_start; int x_end; int y_start; int y_end; int x_mod; int y_mod; int x_grid_step; int y_grid_step; char func[256]; }; struct point last_point; bool use_last_point; /*Coordinates of last drawed point*/ /*bool exit; true if we must exit app*/ static struct plot_conf plot; static void plot_set_default_values(void) { plot.x_start = -(LCD_WIDTH/2); plot.x_end = (LCD_WIDTH/2); plot.y_start = -(LCD_HEIGHT/2); plot.y_end = (LCD_HEIGHT/2); plot.x_mod = 1; plot.y_mod = 1; plot.x_grid_step = 10; rb->strcpy(plot.func,"x*x") ; } static void draw_point(struct point p) { if (!use_last_point) { rb->lcd_drawpixel(p.x,p.y); use_last_point = true; }else { rb->lcd_drawline(last_point.x,last_point.y,p.x,p.y); } } static struct point create_point(int _x, int _y) { struct point tmp; tmp.x = _x; tmp.y = _y; return tmp; } static struct point coord_to_screen_pixel(struct point p) { struct point tmp; tmp.x = (int)((LCD_WIDTH / 2)+p.x); tmp.y = (int)((LCD_HEIGHT / 2)-p.y); return tmp; } static void draw_grid(void) { rb->lcd_set_background(LCD_WHITE); rb->lcd_set_foreground(LCD_BLACK); rb->lcd_vline(LCD_WIDTH/2,0,LCD_HEIGHT); rb->lcd_hline(0,LCD_WIDTH,LCD_HEIGHT/2); int i; int n=0; int sign=1; char buf[32]; for (i=0; i < LCD_WIDTH/2; i+=sign*plot.x_grid_step*plot.x_mod) { rb->lcd_vline(LCD_WIDTH/2+i,LCD_HEIGHT/2-2,LCD_HEIGHT/2+2); rb->snprintf(buf,32,"%d",n); rb->lcd_putsxy(LCD_WIDTH/2+i+1,LCD_HEIGHT/2+4,buf); n+=sign*plot.x_grid_step; } n=0; for (i=0; i < LCD_WIDTH/2 ; i+=plot.x_grid_step*plot.x_mod) { rb->lcd_vline(LCD_WIDTH/2-i,LCD_HEIGHT/2-2,LCD_HEIGHT/2+2); rb->snprintf(buf,32,"%d",n); DEBUGF("%s",buf); rb->lcd_putsxy(LCD_WIDTH/2-i-1,LCD_HEIGHT/2+4,buf); n-=plot.x_grid_step; } } static int count(double x) { static double const_values[2]; const_values[0] = x; const_values[1] = x; const_values[2] = 0; static const char *const_names[]={ "x", "X", 0 }; return (int)x*x;/*ff_eval(plot.func, const_values, const_names, NULL, NULL, NULL, NULL, NULL);*/ } static void draw_plot(void) { DEBUGF("Reach draw plot\n"); double i=1.0; static struct point temp; rb->lcd_clear_display(); draw_grid(); for (i=plot.x_start;i<=plot.x_end;i+=(double)(LCD_WIDTH/plot.x_mod)) { //DEBUGF("Per pixel countion i = 0.%d\n",i*100); temp.x = i*plot.x_mod; temp.y = i*i;/*(int)(count(i)*plot.y_mod);*/ temp = coord_to_screen_pixel(temp); DEBUGF("ym %x\n",plot.y_mod); DEBUGF("y %x\n",temp.y); if ((temp.x0)&\ (temp.y0)) { draw_point(temp); last_point = temp; } } use_last_point = false; rb->lcd_update(); DEBUGF("Exit draw plot\n"); } static bool start_grapher(void) { int button, quit = 0; plot_set_default_values(); draw_plot(); while(!quit) { button=rb->button_get(true); switch(button) { case BUTTON_LEFT: if (plot.x_mod>1) plot.x_mod--; draw_plot(); break; case BUTTON_RIGHT: plot.x_mod++; draw_plot(); break; case BUTTON_UP: plot.y_mod++; draw_plot(); break; case BUTTON_DOWN: if (plot.y_mod>1) plot.y_mod--; draw_plot(); break; case BUTTON_REC: quit=true; break; } } return true; } static bool show_main_menu(void) { int m; bool result; bool rs = true; static const struct menu_item items[] = { { "Grapher", start_grapher }, { "Calculator", NULL }, { "Exit", NULL }, }; m = rb->menu_init(items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL); result = rb->menu_run(m); rb->menu_exit(m); return rs; } enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { (void)parameter; rb = api; show_main_menu(); return PLUGIN_OK; }