📄 lcd-player.c
字号:
/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: lcd-player.c,v 1.35 2003/12/12 13:23:33 bagder Exp $ * * Copyright (C) 2002 by Alan Korr * * 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. * ****************************************************************************/#include "config.h"#include "hwcompat.h"#ifdef HAVE_LCD_CHARCELLS#include "lcd.h"#include "kernel.h"#include "thread.h"#include <string.h>#include <stdlib.h>#include "file.h"#include "debug.h"#include "system.h"#include "font.h"#include "lcd-player-charset.h"/*** definitions ***/#define OLD_LCD_CONTRAST_SET ((char)0xA8)#define OLD_LCD_CRAM ((char)0xB0) /* Characters */#define OLD_LCD_PRAM ((char)0x80) /* Patterns */#define OLD_LCD_IRAM ((char)0xE0) /* Icons */#define NEW_LCD_CONTRAST_SET ((char)0x50)#define NEW_LCD_CRAM ((char)0x80) /* Characters */#define NEW_LCD_PRAM ((char)0xC0) /* Patterns */#define NEW_LCD_IRAM ((char)0x40) /* Icons */#define LCD_CURSOR(x,y) ((char)(lcd_cram+((y)*16+(x))))#define LCD_ICON(i) ((char)(lcd_iram+i))#define SCROLLABLE_LINES 2#define SCROLL_MODE_OFF 0#define SCROLL_MODE_PAUSE 1#define SCROLL_MODE_RUN 2extern unsigned short new_lcd_rocklatin1_to_xlcd[];extern unsigned short old_lcd_rocklatin1_to_xlcd[];extern unsigned char lcd_player_extended_lcd_to_rocklatin1[];extern unsigned char extended_font_player[NO_EXTENDED_LCD_CHARS][8];/*** generic code ***/struct scrollinfo { int mode; char text[MAX_PATH]; int textlen; int offset; int turn_offset; int startx; int starty; long scroll_start_tick; int direction; /* +1 for right or -1 for left*/ int jump_scroll; int jump_scroll_steps;};#define MAX_CURSOR_CHARS 8struct cursorinfo { int len; char text[MAX_CURSOR_CHARS]; int textpos; int y_pos; int x_pos; int divider; int downcount;} cursor;static void scroll_thread(void);static char scroll_stack[DEFAULT_STACK_SIZE];static char scroll_name[] = "scroll";static char scroll_speed = 8; /* updates per second */static int scroll_delay = HZ/2; /* delay before starting scroll */static int jump_scroll_delay = HZ/4; /* delay between jump scroll jumps */static char scroll_spacing = 3; /* spaces between end and start of text */static bool allow_bidirectional_scrolling = true;static int bidir_limit = 50; /* percent */static int jump_scroll = 0; /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */static struct scrollinfo scroll[SCROLLABLE_LINES];static char extended_chars_mapped[NO_EXTENDED_LCD_CHARS];static char extended_pattern_content[8]; /* Which char is mapped in pattern */static char extended_pattern_usage[8]; /* Counting number of times used */static char pattern_size; /* Last pattern, 3 for old LCD, 7 for new LCD */static bool new_lcd;unsigned short *lcd_ascii;static char lcd_contrast_set;static char lcd_cram;static char lcd_pram;static char lcd_iram;unsigned short buffer_xlcd[11][2];unsigned short buffer_lcd_mirror[11][2];#ifdef SIMULATORunsigned char hardware_buffer_lcd[11][2];#endif#define NO_CHAR -1static void lcd_free_pat(int map_ch){ int x, y; unsigned short substitute_char; int pat; pat=extended_chars_mapped[map_ch]; if (pat!=NO_CHAR) { substitute_char=lcd_player_extended_lcd_to_rocklatin1[map_ch]; /* TODO: use a define for the screen width! */ for (x=0; x<11; x++) { /* TODO: use a define for the screen height! */ for (y=0; y<2; y++) { if (map_ch==lcd_ascii[buffer_xlcd[x][y]]-512) { buffer_xlcd[x][y]=substitute_char; buffer_lcd_mirror[x][y]=substitute_char;#ifdef SIMULATOR hardware_buffer_lcd[x][y]=substitute_char;#else lcd_write(true, LCD_CURSOR(x, y)); lcd_write(false, substitute_char);#endif } } } extended_chars_mapped[map_ch]=NO_CHAR; extended_pattern_content[pat]=NO_CHAR; extended_pattern_usage[pat]=0; }#ifdef SIMULATOR lcd_update();#endif}static int lcd_get_free_pat(int ch){ int pat; int last_pat=0; static int last_used_pat=0; int loop; pat=last_used_pat; for (loop=0; loop<=pattern_size; loop++) { pat=(pat+1)&pattern_size; /* Keep 'pat' within limits */ if (extended_pattern_usage[pat]==0) { int map_ch=extended_pattern_content[pat]; if (map_ch != NO_CHAR) { extended_chars_mapped[map_ch]=NO_CHAR; extended_pattern_content[pat]=NO_CHAR; } last_used_pat=pat; return pat; } if (extended_pattern_content[pat]>extended_pattern_content[last_pat]) last_pat=pat; } if (ch<32) { /* Prioritized char */ /* Remove last_pat */ lcd_free_pat(extended_pattern_content[last_pat]); last_used_pat=last_pat; return last_pat; } return NO_CHAR;}void xlcd_update(void){ int x, y; for (x=0; x<11; x++) { for (y=0; y<2; y++) { unsigned short ch=buffer_xlcd[x][y]; unsigned char hw_ch=0xff; if (ch==buffer_lcd_mirror[x][y]) continue; /* No need to redraw */ buffer_lcd_mirror[x][y]=ch; if (ch>=256 && ch<512) { hw_ch=ch-256; } else { int map_ch=lcd_ascii[ch]; if (map_ch<512) { hw_ch=map_ch; } else { map_ch=map_ch-512; if (extended_chars_mapped[map_ch]!=NO_CHAR) { hw_ch=extended_chars_mapped[map_ch]; extended_pattern_usage[hw_ch]++; } else { int pat; pat=lcd_get_free_pat(map_ch); if (pat<0) { DEBUGF("Substitute for %02x (map 0x%02x)" " is used.\n", ch, map_ch); /* Find substitute char */ map_ch= lcd_player_extended_lcd_to_rocklatin1[map_ch]; hw_ch=lcd_ascii[map_ch]; } else {#ifdef DEBUG if (extended_pattern_usage[pat]!=0) { DEBUGF("***Pattern %d is not zero!\n", pat); }#endif extended_chars_mapped[map_ch]=pat; extended_pattern_content[pat]=map_ch; extended_pattern_usage[pat]=1; lcd_define_hw_pattern(pat*8, extended_font_player[map_ch], 8); hw_ch=pat; } } } }#ifdef SIMULATOR hardware_buffer_lcd[x][y]=hw_ch;#else lcd_write(true,LCD_CURSOR(x,y)); lcd_write(false, hw_ch);#endif } } lcd_update();}bool lcdx_putc(int x, int y, unsigned short ch){ int lcd_char; if (buffer_xlcd[x][y]==ch) return false; /* Same char, ignore any update */ lcd_char=lcd_ascii[buffer_xlcd[x][y]]; if (lcd_char>=512) { /* The removed char is a defined pattern, count down the reference. */ extended_pattern_usage[(int)extended_chars_mapped[lcd_char-512]]--;#ifdef DEBUG if (extended_pattern_usage[(int)extended_chars_mapped[lcd_char]]<0) { DEBUGF("**** Mapped char %02x is less than 0!\n", lcd_char); }#endif } buffer_xlcd[x][y]=ch; lcd_char=lcd_ascii[ch]; if (lcd_char>=256) return true; /* Caller shall call xlcd_update() when done */ buffer_lcd_mirror[x][y]=lcd_char;#ifdef SIMULATOR hardware_buffer_lcd[x][y]=lcd_char;#else lcd_write(true, LCD_CURSOR(x, y)); lcd_write(false, lcd_char);#endif return false;}int lcd_default_contrast(void){ return 30;}void lcd_clear_display(void){ int i; bool update=false; DEBUGF("lcd_clear_display()\n"); lcd_stop_scroll(); cursor.len=0; /* Stop cursor */ for (i=0;i<22;i++) update|=lcdx_putc(i%11, i/11, ' '); if (update) xlcd_update();}static void lcd_puts_cont_scroll(int x, int y, unsigned char *string){ bool update=false; DEBUGF("lcd_puts_cont_scroll(%d, %d, \"", x, y); for (; *string && x<11; x++) {#ifdef DEBUGF if (*string>=32 && *string<128) { DEBUGF("%c", *string); } else { DEBUGF("(0x%02x)", *string); }#endif /* We should check if char is over 256 */ update|=lcdx_putc(x, y, *(unsigned char*)string++); } DEBUGF("\")\n"); for (; x<11; x++) update|=lcdx_putc(x, y, ' '); if (update) xlcd_update();}void lcd_puts(int x, int y, unsigned char *string){ DEBUGF("lcd_puts(%d, %d) -> ", x, y); scroll[y].mode=SCROLL_MODE_OFF; return lcd_puts_cont_scroll(x, y, string);}void lcd_put_cursor(int x, int y, char cursor_char){ if (cursor.len == 0) { cursor.text[0]=buffer_xlcd[x][y]; cursor.text[1]=cursor_char; cursor.len=2; cursor.textpos=0; cursor.y_pos=y; cursor.x_pos=x; cursor.downcount=0; cursor.divider=4; }}void lcd_remove_cursor(void){ if (cursor.len!=0) { bool up; cursor.len=0; up = lcdx_putc(cursor.x_pos, cursor.y_pos, cursor.text[0]);#ifdef SIMULATOR if(up) lcd_update();#endif }}void lcd_putc(int x, int y, unsigned short ch){ bool update; DEBUGF("lcd_putc(%d, %d, %d '0x%02x')\n", x, y, ch, ch); if (x<0 || y<0) { return; } update=lcdx_putc(x, y, ch); if (update) xlcd_update();}unsigned char lcd_get_locked_pattern(void){ unsigned char pat=1; while (pat<LAST_RESERVED_CHAR) { if (lcd_ascii[pat]==RESERVED_CHAR) { lcd_ascii[pat]=0x200+pat; return pat; } pat++; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -