static void printreal(double x, bool ex) { bool neg = false; if(x < zero) { neg = true; x = -x; } if(x == zero|| (!neg && x < 0.0001e-99) || (neg && x < 0.001e-99)) { draw_dp(0b10000, 8); draw(0, 7); return;//Zero rounding } if((!neg && x > 9.9999e+99) || (neg && x > 9.999e+99) || x != x) {//NaN test too error = true; draw(15, 7); return;//Overflow } double mask = ((ex)?100000.0:100000000.0);//use exponent mask = ((!neg)?mask:(mask * tenth));//leave space for negative sign if(x >= mask || x <= one/mask) {//sci notation as too big sci(neg, x); return; } dp = (ex?5:8);//set zero placed deciaml //either defered as sci exponent, zero or error printed so far!! bool zeros = (x < one); int check = 0; while((zeros)?(dp > (neg?2:1)):(x < mask)) { check = (int)x; if((double)check == x) break;//exact --dp; x *= 10; } draw_dp(0b10000, dp); printint(neg?-check:check, ex?4:7, zeros);//integer part drawn }
void display_clock(int x, int y, uint32_t tm) { int hh, mm, ss, ms; hh = (int) tm / 3600000; mm = (int) (tm % 3600000) / 60000; ss = (int) (tm % 60000) / 1000; ms = (int) tm % 1000; draw_digit(x, y, hh / 10, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_digit(x, y, hh % 10, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_colon(x, y, GFX_COLOR_RED, GFX_COLOR_BLACK); x += SEG_THICK + SEG_THICK/2;; draw_digit(x, y, mm / 10, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_digit(x, y, mm % 10, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_colon(x, y, GFX_COLOR_RED, GFX_COLOR_BLACK); x += SEG_THICK + SEG_THICK/2;; draw_digit(x, y, ss / 10, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_digit(x, y, ss % 10, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_dp(x, y, GFX_COLOR_RED, GFX_COLOR_BLACK); x += SEG_THICK + SEG_THICK/2; draw_digit(x, y, ms / 100, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_digit(x, y, ms / 10, GFX_COLOR_RED, GFX_COLOR_BLACK); x += DISP_WIDTH + SEG_THICK/2; draw_digit(x, y, ms, GFX_COLOR_RED, GFX_COLOR_BLACK); }
/* * And this is where we will generate our digits * when we copy them with the DMA2D device we can * use the color lookup table to set the values. * in this case we'll use 0, 1, and 2 for background * foreground, and outline color. * * While the digits are kerned in the display they are * drawn here with a box that is DISP_WIDTH + SKEW_MAX * pixels wide, but DISP_HEIGHT pixels high. */ void generate_digits(void) { uint32_t i; gfx_init(digit_draw_pixel, DIGIT_FB_WIDTH, DIGIT_FB_HEIGHT, GFX_FONT_LARGE); /* Cleared to zero (background) */ for (i = 0; i < sizeof(digit_fb); i++) { digit_fb[i] = 0; } for (i = 0; i < 10; i++) { draw_digit(i * (DISP_WIDTH + SKEW_MAX), 0, i, 1, 2); } draw_colon(10 * (DISP_WIDTH + SKEW_MAX), 0, 1, 2); draw_dp(10 * (DISP_WIDTH + SKEW_MAX) + SEG_THICK + SKEW_MAX, 0, 1, 2); /* now the digit_fb memory has the 10 digits 0-9, : and . in it */ }
void tick_clock(struct tm *tick_time, bool stop) { clear(); if((sw_butt&4)==4) { reg.tm_hour = 0; reg.tm_min = 0; reg.tm_sec = 0; sw_butt ^= 4;//reset } if(!stop && (sw_butt&1)==1) sw_tick(); if(++button_sec == 3) mode = delays[mode];//change mode switch(mode) { case 0: draw_dp(0b101010, 3);//time if (!clock_is_24h_style()) { if(tick_time->tm_hour > 11) draw(26, 0);//PM else draw(23, 0);//AM } tock(tick_time, false, clock_is_24h_style()); break; case 1: draw_dp(0b100, 3);//date draw(days[tick_time->tm_mon * 3 + 21], 5); draw(days[tick_time->tm_mon * 3 + 22], 6); draw(days[tick_time->tm_mon * 3 + 23], 7); draw(tick_time->tm_mday/10, 3); draw(tick_time->tm_mday%10, 4); draw(days[tick_time->tm_wday * 3], 0); draw(days[tick_time->tm_wday * 3 + 1], 1); draw(days[tick_time->tm_wday * 3 + 2], 2); break; case 2: draw_dp(0b1010 + (((sw_butt&1)==1)?32:0) + (((sw_butt&2)==2)?0b10001:0), 3);//stopwatch if((sw_butt&2)==2) { tock(&lap, true, true); } else { tock(®, true, true); } break; case 3: printreal(value, false); break; case 4: draw_dp(1<<(direction%5), 8);//score printint(score, 7, false); break; case 5: draw_dp(1<<(direction%5), 8);//level printint(level, 7, false); draw(28, 0);//L break; case 6: draw_dp(1<<(direction%5), 8);//hiscore printint(hiscore, 7, false); draw(18, 0);//H break; default: break; } }