fsosd.c

来自「一个不错的硬盘播放器程序,包含VFD显示程序,红外线遥控程序,硬盘读写程序,及解」· C语言 代码 · 共 636 行 · 第 1/2 页

C
636
字号
/* Copyright 1996, ESS Technology, Inc.                 */
/* SCCSID @(#)fsosd.c	1.97 2/24/98 */

/*
 * $Log$
 */

#include "common.h"
#include "display.h"
#include "util.h"
#include "mvd.h"
#include "fsosd.h"
#include "timedef.h"
#include "vcxi.h"
#include "dsa.h"
#include "const.h"
#include "panel.h"
#include "echo.h"
#include "hm612ndi.h"


/************************************************************************
 * Local OSD definitions						*
 ************************************************************************/
#define EPRINTF(a) 
#define PRIVATE    static

/************************************************************************
 * Global variables declared in this module				*
 ************************************************************************/
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], 
                OSD_new_track[OSD_TRACK_SIZE],
                OSD_new[OSD_MAX_CHAR];  /* "+1" in case of long string */ 


#ifdef BILINGUAL_OSD
unsigned char   OSD_language = 1;	/* 0 : English, 1 : other(Chinese) */
static unsigned char 	*english_ptr[OSD_MAX_REGIONS], 
			*chinese_ptr[OSD_MAX_REGIONS];
static unsigned short	OSD_display_backup=0;
static unsigned short	OSD_update_backup=0;
static unsigned short	OSD_schedule_backup;
#endif


unsigned char	OSD_line_index[16] = {0/*unused*/, 0, 0, 0,
                                             	   1, 1, 1,
                                             	   2, 2, 2,
                                             	   3, 3, 3,
                                             	   4, 4, 4};



/************************************************************************
 * Variables imported from other modules.				*
 ************************************************************************/
IMPORT	int	cur_track_number;
IMPORT	char	disableOsd;



/************************************************************************
 * Private functions							*
 ************************************************************************/
PRIVATE void OSD_cfgline (char, char, char, char, char);

/* 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)
 *         -----------------------------------
 *        | REGION 13 | REGION 14 | REGION 15 |  LINE 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.
     */
    /*
    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, 8, 14);

    OSD_cfgline (OSD_LINE_1, OSD_AREA_2, 0, 4, 12);
    OSD_cfgline (OSD_LINE_2, OSD_AREA_2, 0, 2, 16);
      */
    OSD_cfgline (OSD_LINE_1, OSD_AREA_1, 0, 4, 14);   
    OSD_cfgline (OSD_LINE_2, OSD_AREA_1, 0, 4, 14);   
    OSD_cfgline (OSD_LINE_3, OSD_AREA_1, 0, 4, 14);

    OSD_cfgline (OSD_LINE_1, OSD_AREA_2, 0, 4, 12);
    OSD_cfgline (OSD_LINE_2, OSD_AREA_2, 0, 2, 16);
   
    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();
}

void OSD_init_display(void)
{
    mvd[vid_scn_osd_hstart]	= OSD_HORZ_POS;
    mvd[vid_scn_osd_hend]	= OSD_HORZ_POS + OSD_HORIZ_END;

    mvd[vid_scn_osd_startstop]	= 0x5560; /* cr = 5, b = 21, e = 32 */
    mvd[vid_scn_osd_misc]	= 0x4;	    /* Load palette */
    mvd[vid_scn_osd_palette+ 0] = OSD_CLEAR;            /* 7000,Background   */
    mvd[vid_scn_osd_palette+ 1]	= (OSD_BLACK | 0xb);    /* e00b,Edge  */
    mvd[vid_scn_osd_palette+ 2] = (OSD_GREEN | 0xf);    /* 399f,Extra color  */
    mvd[vid_scn_osd_palette+ 3] = (OSD_WHITE | 0xf);    /* 700f,Foreground  */

    mvd[vid_scn_osd_misc]	= 0x40;  /* Reset mode */
}


/*
 *  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_OSD
void OSD_output(int region, unsigned char *e_msg, unsigned char *c_msg,
                int duration)
#else
void 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;
    OSD_Region  *osd_region_ptr;
    unsigned char *msg;
    /*
    int Local_0 = 1;
    if (Local_0){
        Local_0 = 0;
        return;
    }
              8 */
    region = 5;   
    OSD_language = CHINESE_OSD;

    region_mask = ptrLshift[region-1];
#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 (disableOsd) return;


    osd_region_ptr = &(OSD_regions[region - 1]);
    /* 
     * "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) {
	    if (msg[msg_count] >= FONT_CSTART) {
		OSD_new[new_count++] = msg[msg_count];
	    }
 
	    OSD_new[new_count++] = msg[msg_count++];
	}
    }

/*    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".

⌨️ 快捷键说明

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