⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 display.c

📁 一款MP3 Player Firmware 的原代码,非常有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>#include "printf.h"#include "as31glue.h"#include "parse.h"	// for event codes#include "stricmp.h"#include "sta013.h"#include "main.h"#include "rand.h"#include "playlist.h"#include "treedir.h"#include "display.h"/***************************************************************//**                                                           **//**                     Variables                             **//**                                                           **//***************************************************************/#define DISPLAY_WIDTH 24#define DISPLAYBUF_MAX 250// Which screen is (or should be) displayedtypedef enum {   MAINSCREEN,   AUDIOSCREEN,   TREEDIRSCREEN,   EPARAMSCREEN,   SCREEN_MAX = 3} screen_t;static screen_t current_screen;// Which control on that screen is selectedstatic unsigned char current_control;// Storage for the displayed filenamestatic xdata unsigned char filebuf[DISPLAYBUF_MAX];static xdata unsigned char filebuf_len;static xdata unsigned char filebuf_changed;// Storage for the displayed directory or playlist namestatic xdata unsigned char dirbuf[DISPLAYBUF_MAX];static xdata unsigned char dirbuf_len;static xdata unsigned char dirbuf_changed;// Storage for the id3 tag infostatic xdata char id3_title[DISPLAY_WIDTH+1];static xdata char id3_artist[DISPLAY_WIDTH+1];static xdata char id3_album[DISPLAY_WIDTH+1];static xdata unsigned char id3_title_changed;static xdata unsigned char id3_artist_changed;static xdata unsigned char id3_album_changed;// Set to force all controls to redrawstatic bit force_redraw;// Location and font to use for drawingstatic unsigned char draw_at_x, draw_at_y, draw_font;// Storage of the ID3 tag to displayxdata struct id3_tag_struct id3_tag;// miscstatic unsigned int addr7_backup;static code char lcd_set_xy_cmd[]="\\[\\B";static code char lcd_set_font_cmd[]="\\C";static code char lcd_set_end_cmd[]="\\]\r\n";// on-screen descriptions for play modesstatic code struct {	code char *short_name;	code char *desc_line1;	code char *desc_line2;	code char *desc_line3;} play_mode_description[] = {	//123456789012   12345678901234567890   12345678901234567890   12345678901234567890	{"DirInOrder  ","Play only this",      "directory, in",       "sequence"},	{"DirRandom   ","Play only this",      "directory, in",       "random order"},	{"AllInOrder  ","Play all files in",   "sequence",            ""},	{"RandomPlylst","Play each dir in",    "sequence, choose new","directories randomly"},	{"RandomSelect","Play all files in",   "sequence, but select","randomly on keypress"},	{"AllRandom   ","Play all files in",   "randomized order",    ""}};/***************************************************************//**                                                           **//**                 Function Prototypes                       **//**                                                           **//***************************************************************/// Only static defs belong here... functions callable from other files// should be defined in display.h.static void lcd_begin_draw(void);static void lcd_end_draw(void);#pragma CALLEE-SAVES lcd_begin_draw,lcd_end_drawstatic void call_nonreentrant_function(void (*p)(void), unsigned char parm);static code struct screen_config_struct * cfg_of_current_control(void);static void lcd_do_user_action(code struct screen_config_struct *cfg, event_t event);#pragma CALLEE-SAVES print_string;static void print_string(xdata char *str);#pragma CALLEE-SAVES underscore_to_space;static unsigned char underscore_to_space(xdata char *str);/***************************************************************//**                                                           **//**                Screens Configuration                      **//**                                                           **//***************************************************************/// definition of the tables belowstruct screen_config_struct {	unsigned char x;	unsigned char y;	void (*redraw_routine) (void) reentrant;	unsigned char next_up;	unsigned char next_down;	unsigned char next_left;	unsigned char next_right;	void (*inc_routine) (unsigned char) reentrant;	unsigned char inc_param;	void (*dec_routine) (unsigned char) reentrant;	unsigned char dec_param;};// These tables configure which controls will appear on each screen, where// they appear, what order they are selected using the navigation keys// and what happens when the user attempts to modify with INC/DEC.static code struct screen_config_struct main_screen_config[] = {// X  Y  how_to_redraw  up dn lf rt  inc handler      inc param      dec handler       dec param  {0, 7, redraw_vol,     4, 1, 4, 1, action_vol_up,   0,             action_vol_down,  0},  {0, 0, redraw_play,    0, 3, 0, 2, put_back_event,  E_PLAY_PAUSE,  put_back_event,   E_PLAY_PAUSE},  {6, 0, redraw_mode,    0, 3, 1, 3, play_mode_next,  0,             play_mode_prev,   0},  {0, 1, redraw_file,    1, 4, 1, 4, put_back_event,  E_PLAY_PAUSE,  put_back_event,   E_PLAY_PAUSE},  {0, 2, redraw_dir,     3, 0, 3, 0, put_back_event,  E_PLAY_PAUSE,  put_back_event,   E_PLAY_PAUSE},  {0, 3, redraw_id3_1,   0, 0, 0, 0, no_action,       0,             no_action,        0},  {0, 4, redraw_id3_2,   0, 0, 0, 0, no_action,       0,             no_action,        0},  {0, 5, redraw_id3_3,   0, 0, 0, 0, no_action,       0,             no_action,        0},  {0, 6, redraw_bitrate, 0, 0, 0, 0, no_action,       0,             no_action,        0},  {10,6, redraw_sfreq,   0, 0, 0, 0, no_action,       0,             no_action,        0},  {18,6, redraw_stereo,  0, 0, 0, 0, no_action,       0,             no_action,        0},  {19,0, redraw_time,    0, 0, 0, 0, no_action,       0,             no_action,        0}};static code struct screen_config_struct audio_screen_config[] = {// X  Y  how_to_redraw  up dn lf rt  inc handler      inc param      dec handler       dec param  {0, 7, redraw_vol,     5, 1, 5, 1, action_vol_up,   0,             action_vol_down,  0},  {0, 0, redraw_play,    0, 3, 0, 2, put_back_event,  E_PLAY_PAUSE,  put_back_event,   E_PLAY_PAUSE},  {6, 0, redraw_mode,    0, 3, 1, 3, play_mode_next,  0,             play_mode_prev,   0},  {0, 1, redraw_treble,  1, 4, 1, 4, sta013_tone_up,  PARAM_TREBLE,  sta013_tone_down, PARAM_TREBLE},  {0, 3, redraw_bass,    3, 5, 3, 5, sta013_tone_up,  PARAM_BASS,    sta013_tone_down, PARAM_BASS},  {0, 5, redraw_balance, 4, 0, 4, 0, sta013_tone_up,  PARAM_BALANCE, sta013_tone_down, PARAM_BALANCE},  {19,0, redraw_time,    0, 0, 0, 0, no_action,       0,             no_action,        0}};/***************************************************************//**                                                           **//**     Redraw Handlers For Individual On-screen Controls     **//**                                                           **//***************************************************************/// These redraw handlers actually do all the work of drawing the// on-screen controls.  Each one should store the on-screen data// in a static variables and immediately return if the live data// has not changed, unless the force_redraw bit is set.//// Before drawing, lcd_begin_draw() should be called to set up// the X,Y coordinates and proper font, and lcd_end_draw() should// be called after all drawing to take care of cleanup.static voidredraw_vol(void){	unsigned char attn;	static unsigned char prev_attn=255;	attn = param_value[PARAM_ATTN] - STA013_PARAM_CENTRE + tone_attn;	if (attn == prev_attn && !force_redraw) return;	prev_attn = attn;	if (attn > 99) attn = 99;	lcd_begin_draw();	print("Vol:\\C  ");	if (attn) {		printf("-%2d dB", attn);	} else {		print("  0 dB");	}	lcd_end_draw();}static voidredraw_play(void){	static unsigned char prev_playing=255;	if (playing == prev_playing && !force_redraw) return;	prev_playing = playing;	lcd_begin_draw();	if (playing) {		print("Play ");	} else {		print("Pause");	}	lcd_end_draw();}static voidredraw_mode(void){	static unsigned char prev_play_mode=255;	if (play_mode == prev_play_mode && !force_redraw) return;	prev_play_mode = play_mode;	lcd_begin_draw();	print(play_mode_description[play_mode].short_name);	// TODO: also check for a flash param to disable this balloon description	if (draw_font == 1) {		print("\\K2!0\\K2\"0\\C \r\n+----/         \\\\-------+");		// TODO: change printf to left justify strings within field width		printf("\r\n| %20s |", play_mode_description[play_mode].desc_line1);		printf("\r\n| %20s |", play_mode_description[play_mode].desc_line2);		printf("\r\n| %20s |", play_mode_description[play_mode].desc_line3);		print( "\r\n+----------------------+\r\n");	}	lcd_end_draw();}/* * \[\B !\C \K1! \K3!1bonnie raitt - i cant make you love me\K3!0\K2!0\] **/static voidredraw_scrollable_line(xdata char *str, unsigned char len){	lcd_begin_draw();	if (len <= DISPLAY_WIDTH) {		// disable scrolling		print("\\K2"); print_char(draw_at_y+0x20); print_char('0');		// print string normally		lcd_print_string(str);	} else {		// set scrolling font (is this necessary? ...because lcd_begin_draw set it)		print("\\K1"); print_char(draw_at_y+0x20); print_char(draw_font+0x20);		// begin scrolling buffer fill		print("\\K3"); print_char(draw_at_y+0x20); print_char('1');		// send full string to LCD's scroll buffer		lcd_print_string(str);		print("    ");		// end scrolling buffer fill		print("\\K3"); print_char(draw_at_y+0x20); print_char('0');		// enable automatic horz scrolling by LCD		print("\\K2"); print_char(draw_at_y+0x20); print_char('1');	}	lcd_end_draw();}static voidredraw_file(void){	if (!filebuf_changed && !force_redraw) return;	redraw_scrollable_line(filebuf, filebuf_len);	filebuf_changed = 0;}static voidredraw_dir(void){	if (!dirbuf_changed && !force_redraw) return;	redraw_scrollable_line(dirbuf, dirbuf_len);	dirbuf_changed = 0;}static voidredraw_id3_1(void){	if (!id3_title_changed && !force_redraw) return;	lcd_begin_draw();	lcd_print_string_width(id3_title, 24);	id3_title_changed = 0;	lcd_end_draw();}static voidredraw_id3_2(void){	if (!id3_artist_changed && !force_redraw) return;	lcd_begin_draw();	lcd_print_string_width(id3_artist, 24);	id3_artist_changed = 0;	lcd_end_draw();}static voidredraw_id3_3(void){	if (!id3_album_changed && !force_redraw) return;	lcd_begin_draw();	lcd_print_string_width(id3_album, 24);	id3_album_changed = 0;	lcd_end_draw();}unsigned intget_elapsed_seconds(void){	return (unsigned long)((GetFrameCount() - songStartFrameCount) * (unsigned long)playback.ms_per_frame) / (unsigned long)1000;}static voidredraw_time(void){	static unsigned int prevsec = 0xffff;	unsigned int sec;	//print_char('t');	sec = get_elapsed_seconds();	if (sec == prevsec && !force_redraw) return;	prevsec = sec;	lcd_begin_draw();	printf("%2d:%02d", sec / 60, sec % 60);	lcd_end_draw();}static voidredraw_bitrate(void){	static unsigned int prev_bitrate=0xFFFF;	if (!playback.mode_known) {		lcd_begin_draw();		print("    kbps");		prev_bitrate=0xFFFF;		lcd_end_draw();		return;	}	if (prev_bitrate == playback.bitrate && !force_redraw) return;	prev_bitrate = playback.bitrate;	lcd_begin_draw();	printf("%3d kbps", prev_bitrate);	lcd_end_draw();}static voidredraw_sfreq(void){	static unsigned char prev_freq=0xFF;	if (!playback.mode_known) {		lcd_begin_draw();		print("   kHz");		prev_freq=0xFF;		lcd_end_draw();		return;	}	if (prev_freq == playback.freq && !force_redraw) return;	prev_freq = playback.freq;	lcd_begin_draw();	printf("%2d kHz", prev_freq);	lcd_end_draw();}static voidredraw_stereo(void){	static char prev_stereo=0;	if (!playback.mode_known) {		lcd_begin_draw();		print("      ");		prev_stereo=0;		lcd_end_draw();		return;	}	if (prev_stereo == playback.mode[0] && !force_redraw) return;	prev_stereo = playback.mode[0];	lcd_begin_draw();	printf("%s", playback.mode);	lcd_end_draw();}static voiddraw_bar(unsigned char param){	signed char i, position;	position = param + STA013_MAX_TONE - STA013_PARAM_CENTRE - 2;	if (position < 0) position = 0;	if (position > 21) position = 21;	print_char('[');	for (i=0; i<position; i++) {		print_char((i == 10) ? 'o' : '-');	}	print_char('*');	for (i=position+1; i<=21; i++) {		print_char((i == 10) ? 'o' : '-');	}	print_char(']');}static voidredraw_treble(void){	static unsigned char prev_treble=255;	if (prev_treble == param_value[PARAM_TREBLE] && !force_redraw) return;	prev_treble = param_value[PARAM_TREBLE];	printf("Treble = %d\n", prev_treble);	lcd_begin_draw();	print("Treble\r\n");	draw_bar(prev_treble);	lcd_end_draw();}static voidredraw_bass(void){	static unsigned char prev_bass=255;	if (prev_bass == param_value[PARAM_BASS] && !force_redraw) return;	prev_bass = param_value[PARAM_BASS];	lcd_begin_draw();	print("Bass\r\n");	draw_bar(prev_bass);	lcd_end_draw();}static voidredraw_balance(void){	static unsigned char prev_balance=255;	if (prev_balance == param_value[PARAM_BALANCE] && !force_redraw) return;	prev_balance = param_value[PARAM_BALANCE];	lcd_begin_draw();	print("Balance\r\n");	draw_bar(prev_balance);	lcd_end_draw();}static voidno_action(void) { }/***************************************************************//**                                                           **//**       Redraw Code (call these functions to redraw)        **//**                                                           **//***************************************************************/// These routines take care of redrawing the screens, by calling// the individual redraw routine above, according to the config// table.// redraw all on-screen controls that need updatingvoidlcd_redraw_screen(void){	unsigned char num=0, i=0;	code struct screen_config_struct *cfg;	if (current_screen == TREEDIRSCREEN) {		if (force_redraw) {			force_redraw = 0;			treedir_display();		}		return;	}		if (current_screen == EPARAMSCREEN) {		if (force_redraw) {			force_redraw = 0;			eparam_display();		}		return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -