📄 display.c
字号:
} if (current_screen == MAINSCREEN) { cfg = main_screen_config; num = sizeof(main_screen_config) / sizeof(struct screen_config_struct); playback.mode_known = 0; update_playback_parms(); } if (current_screen == AUDIOSCREEN) { cfg = audio_screen_config; num = sizeof(audio_screen_config) / sizeof(struct screen_config_struct); } for (i=0; i<num; i++) { draw_at_x = cfg->x; draw_at_y = cfg->y; if (i == current_control) { draw_font = 1; } else { draw_font = 0; } call_nonreentrant_function(cfg->redraw_routine, 0); cfg++; } force_redraw = 0;}// force a complete redraw of the entire screenvoidlcd_redraw_screen_force(void){ force_redraw = 1; print("\\I:\\@ 0\\A0"); // display updates off and clear display if (current_screen == TREEDIRSCREEN) { treedir_display(); } else if (current_screen == EPARAMSCREEN) { eparam_display(); } else { lcd_redraw_screen(); } print("\\I8\\I9"); // redraw whole display & turn display updates on}// change which control is selected, and take care of redrawing// the old one as unselected and the new one as selected.static voidset_current_control(unsigned char new_control){ code struct screen_config_struct *cfg; if (current_control == 2 && (current_screen == MAINSCREEN || current_screen == AUDIOSCREEN)) { // a bit of an ugly hack for the balloon descriptions of // play modes... when deselecting the play mode control // we need to force a complete redraw current_control = new_control; lcd_redraw_screen_force(); return; } // else, only redraw the previously selected control normally // and the new control as selected force_redraw = 1; cfg = cfg_of_current_control(); draw_at_x = cfg->x; draw_at_y = cfg->y; draw_font = 0; call_nonreentrant_function(cfg->redraw_routine, 0); current_control = new_control; cfg = cfg_of_current_control(); draw_at_x = cfg->x; draw_at_y = cfg->y; draw_font = 1; call_nonreentrant_function(cfg->redraw_routine, 0); force_redraw = 0;}/***************************************************************//** **//** Handlers For User Actions **//** **//***************************************************************/// handle all user eventsvoidlcd_user_action(event_t event){ if (event == E_LCD_TIMEOUT_TIMER) { if (current_screen != MAINSCREEN || current_control != 0) { current_screen = MAINSCREEN; current_control = 0; lcd_redraw_screen_force(); } return; } set_timer(TIMER_LCD_TIMEOUT, param_screen_timeout()); if (event == E_ENTER) { current_screen++; current_control = 0; if (current_screen > SCREEN_MAX) { current_screen = MAINSCREEN; } lcd_redraw_screen_force(); return; } // all other events are screen specific and sent to a particular screen switch(current_screen) { case MAINSCREEN: lcd_do_user_action(main_screen_config + current_control, event); break; case AUDIOSCREEN: lcd_do_user_action(audio_screen_config + current_control, event); break; case TREEDIRSCREEN: if (treedir_user_action(event)) { lcd_redraw_screen_force(); } break; case EPARAMSCREEN: if (eparam_user_action(event)) { lcd_redraw_screen_force(); } break; default: current_screen = MAINSCREEN; current_control = 0; lcd_redraw_screen_force(); break; }}// handle navigation and inc/dec events according to the config tablestatic voidlcd_do_user_action(code struct screen_config_struct *cfg, event_t event){ switch (event) { case E_UP: set_current_control(cfg->next_up); break; case E_DOWN: set_current_control(cfg->next_down); break; case E_LEFT: set_current_control(cfg->next_left); break; case E_RIGHT: set_current_control(cfg->next_right); break; case E_INC: // (*cfg->inc_routine)(cfg->inc_param); call_nonreentrant_function(cfg->inc_routine, cfg->inc_param); break; case E_DEC: // (*cfg->dec_routine)(cfg->dec_param); call_nonreentrant_function(cfg->dec_routine, cfg->dec_param); break; default: ; } lcd_redraw_screen();}/***************************************************************//** **//** Data Input and Update Routines **//** **//***************************************************************/voidlcd_setup(void){ print("lcd:"); lcd_set_scroll_speed(); parse_event_setup(); lcd_update_backlight_timer(); current_screen = MAINSCREEN; current_control = 0; string_init(filebuf, ' ', DISPLAYBUF_MAX); filebuf_len = 0; string_init(dirbuf, ' ', DISPLAYBUF_MAX); dirbuf_len = 0; lcd_display_id3_init(); lcd_redraw_screen_force();}void lcd_display_id3_init(void){ id3_title[0] = 0; id3_artist[0] = 0; id3_album[0] = 0; id3_title_changed = 1; id3_artist_changed = 1; id3_album_changed = 1;}void lcd_display_id3_struct(void){ strncpy(id3_title, id3_tag.title, sizeof(id3_title)); strncpy(id3_artist, id3_tag.artist, sizeof(id3_artist)); strncpy(id3_album, id3_tag.album, sizeof(id3_album)); id3_title_changed = 1; id3_artist_changed = 1; id3_album_changed = 1;}void lcd_display_id3_none(void){ static xdata char no_id3_string[]=" (no ID3 tag)"; strcpy(id3_artist, no_id3_string); id3_artist_changed = 1;}voidlcd_update_backlight_timer(void){ switch(param_value[PARAM_BACKLIGHT_TIMEOUT]) { case 0: // Never print("\\J20\\J00"); break; case 1: // Always on print("\\J21\\J01"); break; default: // TODO : need to implement timer break; }}voidlcd_set_scroll_speed(){ // do with updates off to reduce flicker printf("\\I:\\K0%d\\I8\\I9\r\n", (int) param_value[PARAM_SCROLL_SPEED]);}void lcd_set_file_name(simm_id name){ if (name == 0) return; addr7_backup = addr7_val; strncpy(filebuf, Addr7(name), sizeof(filebuf)); addr7_val = addr7_backup; filebuf_len = underscore_to_space(filebuf); if (filebuf_len > 4 && str_is_dot_mp3(filebuf + filebuf_len - 4)) { filebuf_len -= 4; filebuf[filebuf_len] = '\0'; } if (filebuf_len <= DISPLAY_WIDTH) { memset(filebuf + filebuf_len, ' ', DISPLAY_WIDTH); filebuf[DISPLAY_WIDTH] = '\0'; } filebuf_changed = 1; lcd_redraw_screen();}void lcd_set_dir_name(simm_id name){ if (name == 0) return; addr7_backup = addr7_val; strncpy(dirbuf, Addr7(name), sizeof(dirbuf)); addr7_val = addr7_backup; dirbuf_len = underscore_to_space(dirbuf); if (dirbuf_len > 4 && str_is_dot_mp3(dirbuf + dirbuf_len - 4)) { dirbuf_len -= 4; dirbuf[dirbuf_len] = '\0'; } if (dirbuf_len <= DISPLAY_WIDTH) { memset(dirbuf + dirbuf_len, ' ', DISPLAY_WIDTH); dirbuf[DISPLAY_WIDTH] = '\0'; } dirbuf_changed = 1; lcd_redraw_screen();}// legacy function... remove soonvoidlcd_set_name(simm_id name, scrollingtext_t type){ if (type == FILENAME) { lcd_set_file_name(name); } else { lcd_set_dir_name(name); }}// legacy function... remove soonvoid lcd_change_menu(unsigned char action){ action; //ignored lcd_redraw_screen();}// legacy function... remove soonvoid lcd_change(param_t parm){ parm; //ignored lcd_redraw_screen();}// legacy function... remove soonvoid lcd_screen_dynamic(const unsigned char refresh){ if (refresh) { lcd_redraw_screen_force(); } else { lcd_redraw_screen(); }}/***************************************************************//** **//** Misc Subroutines **//** **//***************************************************************/static code struct screen_config_struct *cfg_of_current_control(void){ if (current_screen == MAINSCREEN) { return(main_screen_config + current_control); } else { //current_screen == AUDIOSCREEN return(audio_screen_config + current_control); }}#define COUT 0x2030#define PSTR 0x2038static voidlcd_begin_draw(void){ // printf("%s%c%c", lcd_set_xy_cmd, (char)(draw_at_x + 32), (char)(draw_at_y + 32)); // printf("%s%c", lcd_set_font_cmd, (char)(draw_font+32)); _asm mov dptr, #_lcd_set_xy_cmd lcall PSTR mov dptr, #_draw_at_x movx a, @dptr add a, #32 lcall COUT mov dptr, #_draw_at_y movx a, @dptr add a, #32 lcall COUT mov dptr, #_lcd_set_font_cmd lcall PSTR mov dptr, #_draw_font movx a, @dptr add a, #32 lcall COUT _endasm;}static voidlcd_end_draw(void){ print(lcd_set_end_cmd);}static voidcall_nonreentrant_function(void (*p)(void), unsigned char parm){ p; // passed in DPTR parm; // passed @ _call_nonreentrant_function_PARM_2 _asm push dpl push dph mov dptr, #_call_nonreentrant_function_PARM_2 movx a, @dptr mov dpl, a ret ;jumps to funtion _endasm;}static voidprint_string(xdata char *str){ str; _asmprint_string_loop: movx a, @dptr jz print_string_end lcall COUT inc dptr sjmp print_string_loopprint_string_end: _endasm;}#pragma SAVE#pragma LESS_PEDANTICstatic unsigned charunderscore_to_space(xdata char *str){#if 0 unsigned char len=0; while (*str) { if (*str == '_') *str = ' '; len++; str++; } return len;#endif str; // passed in dptr _asm mov b, #000001$: movx a, @dptr jz 00003$ //cjne a, #'_', 00002$ cjne a, #0x5F, 00002$ //mov a, #' ' mov a, #0x20 movx @dptr, a00002$: inc b inc dptr sjmp 00001$00003$: mov dpl, b _endasm;}#pragma RESTOREvoidlcd_print_char(char c){ if (c == '\\') { print_char(0x5C); print_char(0x5C); } else if (c == 127) { print_char(0x5C); print_char(0x5F); } else if ((c & 0xE0) == 0) { print_char(0x5C); print_char(c + 32); } else if ((c & 0xE0) == 0x80) { print_char(0x5C); print_char(c - 32); } else { print_char(c); }}voidlcd_print_string(xdata char *str){ while (*str) { lcd_print_char(*str); str++; }}voidlcd_print_string_width(xdata char *str, unsigned char width){ str; // passed in DPTR width; // passed at _lcd_print_string_PARM_2 while (*str && width) { lcd_print_char(*str); str++; width--; } while (width) { print_char(' '); width--; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -