fsosd.c
来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 1,013 行 · 第 1/2 页
C
1,013 行
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)fsosd.c 4.17 03/03/04 *//* * $Log$ */#include "vcxi.h"#include "memmap.h"#include "display.h"#include "util.h"#include "fsosd.h"#include "timedef.h"#include "const.h"#include "echo.h"#include "cd.h"#ifdef PLAY20#include "dsa.h"#include "panel.h"#endif#ifdef EQUALIZER#include "eq.h"#endif#ifdef MP3#include "mp3.h"#endif/************************************************************************ * Local OSD definitions * ************************************************************************/#define EPRINTF(a) #define PRIVATE static/************************************************************************ * Global variables declared in this module * ************************************************************************/static short OSD_palette[] = { (OSD_CLEAR | 0x0), (OSD_BLACK | 0xb), (OSD_GREEN | 0xf), (OSD_WHITE | 0xf), /* custom colors */ (OSD_RED | 0xf)};unsigned char OSD_lines[OSD_MAX_LINES][OSD_MAX_CHAR];OSD_Region OSD_regions[OSD_MAX_REGIONS]; unsigned short OSD_displayed_regions=0; /* bits indicate region(s) with */ /* message actively displayed */unsigned short OSD_scheduled_regions=0; /* bits indicate region(s) */ /* scheduled for clearing */unsigned short OSD_suppressed_regions=0; /* bits indicate region(s) whose */ /* display(s) are suppressed */unsigned short OSD_update_regions=0; /* regions to be updated in dram */int OSD_schedule_time[OSD_MAX_REGIONS];unsigned char OSD_new_time[OSD_TIME_SIZE+1], OSD_new_track[OSD_TRACK_SIZE+1], OSD_new[OSD_MAX_CHAR]; /* "+1" in case of long string */ #ifdef BILINGUAL_OSDunsigned char OSD_language = 1; /* 0 : English, 1 : other(Chinese) */static unsigned char *english_ptr[OSD_MAX_REGIONS], *chinese_ptr[OSD_MAX_REGIONS];#endifunsigned char OSD_line_index[16] = {0/*unused*/, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};#ifdef PLAY20unsigned char OSD_time_minute=0; /* BCD time for minute */unsigned char OSD_time_second=0; /* BCD time for second */unsigned int OSD_next_update; /* time next update allowed */ unsigned char OSD_update_time;#endif/************************************************************************ * Variables imported from other modules. * ************************************************************************/IMPORT int cur_track_number;IMPORT char disableOsd; /************************************************************************ * Private variables * ************************************************************************//************************************************************************ * Private functions * ************************************************************************//* PV FSOSD * * Example Full Screen OSD Configuration: * * AREA 1______________________________ * | | | | * | REGION 1 | REGION 2 | REGION 3 | LINE 1 (AREA 1) * ----------------------------------- * | REGION 4 | REGION 5 | REGION 6 | LINE 2 * ----------------------------------- * | REGION 7 | REGION 8 | REGION 9 | LINE 3 * ------------------------------------- * . . . * . . . * . . . * AREA 2______________________________ * | | | | * | REGION 10 | REGION 11 | REGION 12 | LINE 1 (AREA 2) * ------------------------------------- * * * * NOTE: When reconfiguring OSD Areas, verify that the following defines are * correct for your intended layout. * 1. OSD_TOTAL_AREAS * 2. OSD_LINES_IN_AREA_1 and OSD_LINES_IN_AREA_2 * 3. OSD_TIME_REGION & OSD_TIME_REGION_MASK * 4. OSD_TRACK_REGION & OSD_TRACK_REGION_MASK * * * * * * * * * * * * * * * * * * * * Initialize OSD parameters. */void OSD_init(){ int i; EPRINTF(("&Lines: 0x%x, &Regions: 0x%x\n", OSD_lines[0], OSD_regions)); /* Example: line divided into three regions * OSD_cfgline (OSD_LINE_#, OSD_AREA_#, 0, 7, 14); * * [ 0 to 6 | 7 to 13 | 14 to 19 ] * * NOTE: * 1) Maximum of five lines (total) allowed * 2) No longer limited to even "start" values. */#ifdef P4O OSD_cfgline (OSD_LINE_1, OSD_AREA_1, 0, 8, 14); OSD_cfgline (OSD_LINE_2, OSD_AREA_1, 0, 8, 10); OSD_cfgline (OSD_LINE_3, OSD_AREA_1, 0, 4, 12); OSD_cfgline (OSD_LINE_1, OSD_AREA_2, 0, 2, 16);#else /* not P4O */ OSD_cfgline (OSD_LINE_1, OSD_AREA_1, 0, 7, 14); OSD_cfgline (OSD_LINE_2, OSD_AREA_1, 0, 8, 16); OSD_cfgline (OSD_LINE_3, OSD_AREA_1, 0, 6, 14); OSD_cfgline (OSD_LINE_1, OSD_AREA_2, 0, 2, 16);#endif /* P4O */ /* Initializing text, track and time */ for (i = 0; i < OSD_MAX_CHAR; i++) { OSD_new[i] = ' '; if (i < OSD_MAX_REGIONS) OSD_schedule_time[i] = 0; if (i < OSD_TIME_SIZE) { OSD_new_time[i] = ' '; } if (i < OSD_TRACK_SIZE) { OSD_new_track[i] = ' '; } } OSD_init_display();}/* * OSD_load_palette(): * Load palette with specified colors. * * Inputs: * color - color4[15:12] | color3[11:8] | color2[7:4] | color1[3:0] * ..index values into OSD_palette{}. * * NOTE: color=0x3210, is standard palette. */void OSD_load_palette(uint color){ int i, j; /* Load OSD palette */ mvd[vid_scn_osd_misc] = 0x4; for(j = 0; j < 4; j++) { i = color&0xf; mvd[vid_scn_osd_palette + j] = OSD_palette[i]; color>>=4; }} void OSD_init_display(void){ mvd[vid_scn_osd_hstart] = OSD_HORZ_POS; mvd[vid_scn_osd_hend] = OSD_HORZ_POS + OSD_HORIZ_END; /* cr = 5, b = 21, e = 32 */ mvd[vid_scn_osd_startstop] = (5<<12)|(0x23<<6)|0x20; OSD_load_palette(0x3210); /* standard palette */ mvd[vid_scn_osd_misc] = 0x40; /* Reset mode */}void OSD_set_vstart_end(int scn_height){ if (scn_height == 240) { vid_scn_osd_vstart1 = OSD_ntsc_vert_pos1; vid_scn_osd_vend1 = OSD_ntsc_vert_end1; vid_scn_osd_vstart2 = OSD_ntsc_vert_pos2; vid_scn_osd_vend2 = OSD_ntsc_vert_end2; } else { vid_scn_osd_vstart1 = OSD_pal_vert_pos1; vid_scn_osd_vend1 = OSD_pal_vert_end1; vid_scn_osd_vstart2 = OSD_pal_vert_pos2; vid_scn_osd_vend2 = OSD_pal_vert_end2; }}/* * OSD_cfgline(): * Function to configure regions in a particular OSD line. * * Inputs: * line_num - Index into the OSD 'line' structure. * area_num - Index into the OSD 'area' structure. * start1 - Defines the starting index of region_1 in the line. * start2 - Defines the starting index of region_2 in the line. * start3 - Defines the starting index of region_3 in the line. * * NOTE: 'start#' values are restricted to even numbers! * (using odd values may result in incomplete clearing of suppressed regions) */void OSD_cfgline (char line_num, char area_num, char start1, char start2, char start3){ int i; OSD_Region *osd_region_ptr = &(OSD_regions[(area_num * OSD_REGIONS_PER_LINE * OSD_LINES_IN_AREA_1) + (OSD_REGIONS_PER_LINE * line_num)]); osd_region_ptr->start = start1; (osd_region_ptr + 1)->start = start2; (osd_region_ptr + 2)->start = start3; /* NOTE: "end" holds the region's last character index position + 1, * so that handling of message size is simpler,i.e. "size = end-start". */ osd_region_ptr->end = start2; (osd_region_ptr + 1)->end = start3; (osd_region_ptr + 2)->end = OSD_MAX_CHAR; for (i = 0; i < OSD_MAX_CHAR; i++) OSD_lines[line_num + area_num * OSD_LINES_IN_AREA_1][i] = 0xff;}/* * OSD_output(): * On screen display a given message at a given region for a given * duration. If this message is too long, the next region(s) will be * "suppressed" automatically. * * Inputs: * region: One of fifteen predefined OSD regions * msg: Message to display * duration: Number of seconds to display before disappearing. * If duration is 0, then the message will be * displayed until changed explicitly. * * Additional parameters for customized OSD_output * * c_msg: Chinese OSD string */#ifdef BILINGUAL_OSDvoid OSD_output(int region, unsigned char *e_msg, unsigned char *c_msg, int duration)#elsevoid OSD_output(int region, unsigned char *osd_msg, int duration)#endif{ int new_count, curr_end, msg_count; unsigned short tmp_mask; unsigned short region_mask = ptrLshift[region-1]; OSD_Region *osd_region_ptr; unsigned char *msg;#ifdef BILINGUAL_OSD msg = (OSD_language == CHINESE_OSD) ? c_msg : e_msg; /* chinese first */ chinese_ptr[region-1] = c_msg; english_ptr[region-1] = e_msg;#else msg = osd_msg;#endif if (OSD_suppressed_regions & region_mask) return; /* region is suppressed */#if (P1O || P2O || P3O || P4O) if (disableOsd) return;#endif osd_region_ptr = &(OSD_regions[region - 1]); #ifdef USE_CN_HEADER /* * "new_count" holds the physical number of character spaces used. */ new_count = 0; while (msg[new_count] != '\0' && new_count < OSD_MAX_CHAR) { OSD_new[new_count] = msg[new_count++]; }#else /* * "new_count" holds the physical number of character spaces used. * "msg_count" holds the logical number of characters used. * * For example, in messages that use exclusively "English" fonts, * new_count == msg_count. Whereas, in messages that use only * "Chinese" fonts, new_count == 2*msg_count. */ new_count = msg_count = 0; while (msg[msg_count] != '\0' && new_count < OSD_MAX_CHAR) {#ifdef BILINGUAL_OSD if (msg[msg_count] >= FONT_CSTART) { OSD_new[new_count++] = msg[msg_count]; }#endif OSD_new[new_count++] = msg[msg_count++]; }#endif /* USE_CN_HEADER *//* OSD_new[new_count] = '\0'; EPRINTF(("osd_new: %s\n", OSD_new));*/ /* NOTE: "end" holds the region's last character index position + 1, * so that handling of message size is simpler,i.e. "size = end-start". */ /* curr_end now holds size of current message */ curr_end = (int)(osd_region_ptr->end - osd_region_ptr->start); /* * Set end so that old msg is cleaned up... * We have a combination of conditions to account for when * resetting the end of the message to be displayed: * 1. Has the region been cleared ? * 2. If the region has not been cleared, is the new message * shorter than the current message? If so, we will use * the current message's "end". This serves to clean up * the currently displayed message. * 3. For all other cases we use the new message's "end", * determined by the new message's length. */ if ((new_count < curr_end) && (OSD_displayed_regions & region_mask)) { for ( ; new_count < curr_end; new_count++) { asm("nop"); OSD_new[new_count] = ' '; } } else { /* NOTE: "end" holds the region's last character index position + 1, * so that handling of message size is simpler,i.e. "size = end-start". */ osd_region_ptr->end = osd_region_ptr->start + (char)new_count; /* If message is too long we need to suppress region(s) that follows */ if (region_mask & (OSD_SECT_1|OSD_SECT_2)) { /* first or second region in line */ if (osd_region_ptr->end > ((osd_region_ptr + 1)->start) ) { /* Message overlaps next region */ tmp_mask = (region_mask << 1); /* suppress display of next region */ OSD_suppressed_regions |= tmp_mask; /* unset scheduled clear */ OSD_scheduled_regions &= ~tmp_mask; if (!(tmp_mask & (OSD_TRACK_REGION_MASK|OSD_TIME_REGION_MASK))) OSD_displayed_regions &= ~tmp_mask; /* Fill in suppressed areas with blanks */ curr_end = (int)((osd_region_ptr + 1)->end - osd_region_ptr->start); if (curr_end > OSD_MAX_CHAR) curr_end = OSD_MAX_CHAR; for ( ; new_count < curr_end; new_count++) { asm("nop"); OSD_new[new_count] = ' '; } if (region_mask & OSD_SECT_1) /* first region in line */ { tmp_mask = (region_mask << 2); if (osd_region_ptr->end > (osd_region_ptr + 2)->start) { /* Message is longer than current and next region */ /* Next 2 regions will be suppressed */ OSD_suppressed_regions |= tmp_mask; OSD_scheduled_regions &= ~tmp_mask; if (!(tmp_mask & (OSD_TRACK_REGION_MASK|OSD_TIME_REGION_MASK))) OSD_displayed_regions &= ~tmp_mask; /* Fill in suppressed areas with blanks */ curr_end = OSD_MAX_CHAR; for ( ; new_count < curr_end; new_count++) { asm("nop"); OSD_new[new_count] = ' '; } } else /* unsuppress last region in line just in case */ OSD_suppressed_regions &= ~tmp_mask; } /* Reset end for added 'blanks' */ if (new_count == curr_end) osd_region_ptr->end = osd_region_ptr->start + curr_end; } } /* Restrict message length */ if (osd_region_ptr->end > OSD_MAX_CHAR) osd_region_ptr->end = OSD_MAX_CHAR; } /* * If a non-zero duration is specified, then schedule an event * at some future time to clear this message. If no duration is * specified, then OSD_schedule_time needs to be cleared. In any * case, a previous scheduled event is dumped. */ if (!duration) { OSD_scheduled_regions &= ~region_mask; /* clear bit */ } else {#ifdef BILINGUAL_OSD if (duration != OSD_KEEP_TIMEOUT)#endif { OSD_schedule_time[region-1] = glbTimer + ((int) ONE_SECOND * duration); OSD_scheduled_regions |= region_mask; /* set bit */ } } /* Set displayed and update flags */ OSD_displayed_regions |= region_mask; OSD_update_regions |= region_mask; /* set for copy to dram */ OSD_update_info(); /* Let this routine update the screen*/}/* * OSD_update_info(): * This routine updates track and/or time information. Track and time * display can be controlled by defines. */void OSD_update_info(){ int i, tmp;#ifdef PLAY20 if ( (OSD_displayed_regions & OSD_TIME_REGION_MASK) && !(OSD_suppressed_regions & OSD_TIME_REGION_MASK) ) { tmp = (D2A_BLANK << 20) | (OSD_time_minute << 12) | (D2A_COLON << 8) | OSD_time_second; for (i=5; i>=0; i--) { OSD_new_time[i] = T_digit2ascii[tmp&0xf]; tmp >>= 4; } OSD_update_regions |= OSD_TIME_REGION_MASK; /* We use two complementary methods to update time: * 1) through servo Q-code when we receive "seconds" and * 2) "one-second" timer, in case someone holds the disc * and prevents Q-code update. This is needed for * MP3/WMA and CDDA w/ANTI_SHOCK. * So we'll need to set a minumum time for next update, * to prevent "quick" seconds update. */ OSD_next_update = glbTimer + 50; } if ( (OSD_displayed_regions & OSD_TRACK_REGION_MASK) && !(OSD_suppressed_regions & OSD_TRACK_REGION_MASK) ) { i = UTIL_hex2bcd(cur_track_number); tmp = (i<<16) | (D2A_SLASH<<12); if (i < 0x100) tmp |= (D2A_BLANK<<24); if (bcd_num_of_track < 0x100) { tmp |= ((bcd_num_of_track<<4) | D2A_BLANK); } else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?