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 + -
显示快捷键?