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

📄 osdcore.c

📁 ESS3890+SL原代码(1*16内存)
💻 C
字号:
/* Copyright 1996, ESS Technology, Inc.					*//* SCCSID @(#)osdcore.c	4.8 04/27/04 */ /* * $Log$ */#include "common.h"#include "memmap.h"#include "const.h"#include "display.h"#include "fsosd.h"#include "util.h"#include "mvd.h"#ifdef PLAY20#include "vcd.h"#endif#define EPRINTF(a)/************************************************************************ * Local variables ************************************************************************/static int         osd_voffset;static int         osd_hoffset = 0;/* * The following OSD routine is marginally time critical, so it can  * either be in SRAM or ROM. If there is still space in SRAM, then it * should be included in SRAM; otherwise, it can sit in ROM. */#ifdef USE_VWCOMP#define DECODE_SIZE	192 /* Bytes */extern int newicon_decomp(uchar *out, uchar *in, uchar *codebook, 			  int width, int height);#else#define DECODE_SIZE	24  /* Bytes */extern void OSD_decompression (int, unsigned char *, 			       unsigned char *, 			       unsigned char *, 			       unsigned short *, int);#endif /* USE_VWCOMP *//* * Actual updating of DRAM for OSD data. * * Input: *	clean_up: *		 0 = Normal OSD operation. *		 1 = Flag to use OSD_new to clear DRAM for Time/Track. *		-1 = Flag to use OSD_blink_msg to simulate blinking. */void OSD_copy_data(int clean_up){    int pos, dest;    OSD_Region 	*osd_region;    unsigned short  	region_mask;    int     		count, end, region, size;    unsigned char    	*current, *osd_new;    int big;			/* Is the font single/big		*/    unsigned int head;		/* Region offset (in byte)		*/    int offset;			/* Position offset in a region.		*/        while (OSD_update_regions)    {        if ((OSD_update_regions & (OSD_TIME_REGION_MASK |				   OSD_TRACK_REGION_MASK))) { 	    if (OSD_update_regions & OSD_TIME_REGION_MASK) {        		region = OSD_TIME_REGION;		region_mask = OSD_TIME_REGION_MASK;                            		osd_new = OSD_new_time;            		size = OSD_TIME_SIZE;	    }	    else { /* Track region */		region = OSD_TRACK_REGION;		region_mask = OSD_TRACK_REGION_MASK;                            		osd_new = OSD_new_track;		size = OSD_TRACK_SIZE;	    }            current = OSD_lines[OSD_LINE_NUM(region)];	    osd_region = &(OSD_regions[region - 1]);            if (clean_up == 1) {                end = OSD_MAX_CHAR; /* we're in clearAllOsd() */                osd_new = OSD_new;  /* use 'blanks' */                      } else {                end = osd_region->end = osd_region->start + size;            }            OSD_update_regions &= ~region_mask;        }        else         {   /* let's find region that needs updating */	    for (region = 0; region < OSD_MAX_REGIONS; region++)	    {                region_mask = ptrLshift[region];		if (OSD_update_regions & region_mask)		{		    OSD_update_regions &= ~region_mask;		    break;		}	    }            osd_region = &(OSD_regions[region]);	    region++;  /* now holds region number..previously held index */                end = (int)(osd_region->end);            current = OSD_lines[OSD_LINE_NUM(region)];	    osd_new = OSD_new;                    }	/* 	 * pos:		Character position in current[]	 * count:	Character position in osd_new[]	 * offset:	offset*6 is OSD offset (in bytes) w.r.t. 	 *		the beginning of the specific OSD line.	 * head:	DRAM offset for between of OSD (in DWORD)	 * big:		"Big" character (i.e. each of them is twice	 *		the size of small character)	 * odd:		If "offset" is odd	 */	offset = pos = (int)(osd_region->start); 	head = (OSD_start +		OSD_LINE_NUM(region) * OSD_dram_dx *	        OSD_CHAR_HEIGHT/2) << 2;        for (count = 0; offset < end; ) {	    unsigned int new_ch, ctmp = osd_new[count];	    /* Check if we really need to copy */#ifdef USE_CN_HEADER	    big = (ctmp == CN_HEADER);	    if (big) {		ctmp = osd_new[count+1];				new_ch = ((current[pos+1] != CN_HEADER) || 			  (current[pos] != ctmp));	    } else {		new_ch = ((current[pos+1] == CN_HEADER) ||			  (current[pos] != ctmp));	    }#else	    big = (ctmp >= FONT_CSTART);	    new_ch = (current[pos] != ctmp);#endif	    	    if (new_ch) {				/* 6Bytes per char width */		dest = head + (offset << 2) + (offset << 1);	    		OSD_copy_one_char(ctmp, big, dest, OSD_dram_dx);		current[pos] = ctmp;	    }			    count++; pos++; offset++;	    if (big) {#ifdef USE_CN_HEADER		current[pos] = CN_HEADER; /* for checking new char */#else		current[pos] = ctmp; /* 'big' uses 2 char positions */#endif		count++; 		offset++;		pos++;	    }	}    }}/* * Put the given character (ctmp) into the destination DRAM (dest). * * Inputs: *	ctmp:	Target character *	big:	Is it a big (double width) or small (single width) character *	dest:	Destination DRAM offset (byte offset) *	width:	Width of a OSD line (in DWORDS) */void OSD_copy_one_char(ctmp, big, dest, width)unsigned int ctmp;int big, dest, width;{    int tmp;    unsigned short *srcptr;    unsigned int *lptr;    unsigned int *dptr;    unsigned int odd;		/* Is it odd/even WORD boundary?	*/    unsigned int mem;	/* Memory data (on DWORD access)	*/    int new = 1;		/* A new character			*/    unsigned char scratch_buf[DECODE_SIZE];/* To store decompressed dat	*/    unsigned short *bufend = (unsigned short *) &scratch_buf[DECODE_SIZE];    unsigned char *code_book, *comp_font;    unsigned short *offset_tbl;     /*     * If the offset is in WORD boundary (instead of DWORD     * boundary), then drop the last 2b, so it is always     * DWORD aligned from here.     */    odd = 0;    if (dest & 0x2) {	odd = 1;	dest &= ~2;    }    /* Translate it to non-cachable DRAM offset */    dptr = (int *) (x12000000 + dest);        /*      * Look up from small (English) font or big (Chinese) font     * table?     */#ifdef USE_CN_HEADER#ifdef BILINGUAL_OSD    if (big) {	tmp = 2;	/* Chinese font data */	ctmp -= FONT_CSTART;	code_book = T_osd_cfonts_code_book; 	comp_font = T_osd_cfonts_comp_font;	offset_tbl = T_osd_cfonts_offset_tbl;    } else#endif    {	tmp = 1;	/* English font data */	ctmp -= FONT_START;	code_book = T_osd_efonts_code_book; 	comp_font = T_osd_efonts_comp_font;	offset_tbl = T_osd_efonts_offset_tbl;    }    #else    /*      * If not USE_CN_HEADER, "small" & "big" are contained in the      * same table.     */    ctmp -= FONT_START;    code_book = T_osd_code_book;    comp_font = T_osd_comp_font;    offset_tbl = T_osd_offset_tbl;#endif /* USE_CN_HEADER */#ifdef USE_VWCOMP    /* Decompress 24B into scratch_buf */    newicon_decomp(scratch_buf, comp_font+offset_tbl[ctmp], 		   code_book,  6*tmp,  OSD_CHAR_HEIGHT/2);    srcptr = (unsigned short *)scratch_buf;#else    srcptr = bufend;#endif /* USE_VWCOMP */    /* Write one small/big character at a time */    for (tmp = 0; tmp < (OSD_CHAR_HEIGHT/2); tmp++) {#ifndef USE_VWCOMP	if (srcptr >= bufend) {	    /* Decompress 24B into scratch_buf */	    OSD_decompression(ctmp, scratch_buf, code_book,			      comp_font, offset_tbl, new);	    srcptr = (unsigned short *)scratch_buf;	    new = 0;	/* Next 24B are no longer from a new character	*/	}#endif	if (odd) {	    /* Target DRAM starts from WORD boundary */	    mem = *dptr & 0xffff0000;	    *dptr = *srcptr | mem;	    *(dptr+1) = *(srcptr+1) << 16 | *(srcptr+2);	    if (big) {		*(dptr+2) = *(srcptr+3) << 16 | *(srcptr+4);		mem = *(dptr+3) & 0xffff;		*(dptr+3) = *(srcptr+5) << 16 | mem;		srcptr += 3;	    }	} else {	    /* Target DRAM starts from DWORD boundary */	    if (big) {		lptr = (unsigned int *) srcptr;		*dptr = *lptr;		*(dptr+1) = *(lptr+1);		*(dptr+2) = *(lptr+2);		srcptr += 3;	    } else {		*dptr = (*srcptr << 16) | *(srcptr+1);		mem = *(dptr+1) & 0xffff;		*(dptr+1) = (*(srcptr+2) << 16) | mem;	    }	}	srcptr += 3;	dptr += width;    }}/* *  OSD_clear_all(): *  This function is used to clear all of the OSD regions at once.  *  Calling this function is much more efficient than clearing fifteen  *  regions with repeated calls to OSD_clear_region(). */voidOSD_clear_all(int dummy){    int i, j;    int osd_size_to_clear;    osd_size_to_clear = (OSD_displayed_regions & NPOSD_MASK) ?	OSD_AREA1_SIZE :  OSD_size;    dram_clear(OSD_start, osd_size_to_clear);     /* Establish difference so that OSD_copy_data() will update */    for (i = 0; i < OSD_MAX_LINES; i++)     {	for (j = 0; j < OSD_MAX_CHAR; j ++) 	{	    OSD_lines[i][j] = FONT_SPACE;	}    }    /* Clearing status bits */    OSD_scheduled_regions =    OSD_update_regions =     OSD_suppressed_regions = 0;    OSD_displayed_regions &= NPOSD_MASK; } /***************************************************************************** Vertical shift *****************************************************************************/void OSD_vertical_shift(int offset){    osd_voffset = offset;}/***************************************************************************** Horizontal shift *****************************************************************************/void OSD_horizontal_shift(int offset){    osd_hoffset = offset;}/* Called in display interrupt service */void OSD_setup(int field) {    int dy;    int ystart, ysize;    mvd[vid_scn_osd_hstart] = OSD_HORZ_POS + osd_hoffset;         mvd[vid_scn_osd_hend] = OSD_HORZ_POS+(OSD_dram_dx<<4)+osd_hoffset;      if (field == -1) {	mvd[vid_scn_osd_vstart] = vid_scn_osd_vstart2 + osd_voffset;	mvd[vid_scn_osd_vend] = vid_scn_osd_vend2 + osd_voffset;    } else {	mvd[vid_scn_osd_vstart] = vid_scn_osd_vstart1 + osd_voffset;	mvd[vid_scn_osd_vend] = vid_scn_osd_vend1 + osd_voffset;		if (OSD_displayed_regions) {	    dy = OSD_dram_dy;#ifdef NON_PLAY_OSD	    if (OSD_displayed_regions & NPOSD_MASK) {		dy += NPOSD_DRAM_DY;	    }#endif	    buscon_xfer(ysn, BDMA_USEDX, OSD_start, dy, OSD_dram_dx);	    mvd[vid_scn_osd_misc] = (OSD_total_areas == 2) ? 0x9 : 0x1;	}    } }#ifdef EQUALIZER/* * OSD_paint_rect(): *	Paint a specified OSD region (inclusive) * * Inputs: *         X   *   +------> *   |       (x1,y1) pixel *   |          +--------------------------      --- * Y |          |                          |      ^ *   V          |         (color)          |    height(in dram) *              |                          |      v *               --------------------------+     --- *                                          *              |<-------- width --------->| * * Limits: *	- x1 >= 0, (x1+width) <= 480 (24 * OSD_MAX_CHAR) *	- y1 >= 0, (y1+height) <= 80 (16 * OSD_MAX_LINES)  */#define PIXELS_IN_DW	16 /* 16 for 2b-OSD, 8 for 4b-OSD */void OSD_paint_rect(int x1, int y1, int width, int height, 		       unsigned int color){    int i, tmp, offset, dw_offset, ndw, dest;    unsigned int *dptr, *hstart;    unsigned int data, mask, end_mask;    unsigned short OSD_masks[] = { 	0xffff,0x3fff,0x0fff,0x03ff,	0x00ff,0x003f,0x000f,0x0003#if 0 /*for 4bit osd*/	0xffff,0x0fff,0x00ff,0x000f#endif    };     /* Beware of limits above..only rudimentary checks here */    if (x1 < 0 || (x1 + width) > 480 || y1 < 0 || (y1 + height) > 80) return;    if ((width<PIXELS_IN_DW) || (height<=0)) return;    /* "color" == 16 pixel length of index of OSD_palette_2b[] */    data = (color<<16) | color; /* 16 pixel length of color */    /* dram start */    dw_offset = (x1/PIXELS_IN_DW);     offset = x1 - (dw_offset * PIXELS_IN_DW);    dest = OSD_start + y1*OSD_dram_dx + dw_offset; /* for buscon */    dptr = (unsigned int *)dram(dest);        /* 0 <= offset <= 15 */    mask = (offset < PIXELS_IN_DW/2) ? 	(unsigned int) ((OSD_masks[offset]<<16) | 0xffff) :	(unsigned int) (OSD_masks[offset-PIXELS_IN_DW/2]);    /* currently only used for EQ (width over one DW)..save some code */    hstart = dptr;    tmp = width - (PIXELS_IN_DW-offset);    ndw = (tmp/PIXELS_IN_DW);    offset = tmp - (ndw*PIXELS_IN_DW);        /* 0 <= offset <= 15 */    end_mask = (offset < PIXELS_IN_DW/2) ? 	(unsigned int) ((OSD_masks[offset]<<16) | 0xffff) :	(unsigned int) (OSD_masks[offset-PIXELS_IN_DW/2]);        for (i = 0; i < height; i++) {	*dptr = ((*dptr++ & ~mask) | (data & mask));	tmp = ndw;	while (tmp) {	    *dptr++ = data;	    tmp--;	};	*dptr = ((*dptr & end_mask) | (data & ~end_mask));	dptr = hstart += OSD_dram_dx;    }}/*  * OSD_put_one_char(): *	Put a font at specified location with specified color palette.  * * Inputs: *	ch_x, ch_y: character location (not pixel location) *	ch: single font to display * * NOTE:  *	- only for 2bit mode. */void OSD_put_one_char(int ch_x, int ch_y, uchar ch){    int i, dest, tmp;    /* dram start in byte address */    dest = ((OSD_start + ch_y*OSD_dram_dx*OSD_CHAR_HEIGHT/2)<<2) + 	(ch_x<<2) + (ch_x<<1);        OSD_copy_one_char(ch, 0, dest, OSD_dram_dx);}/*  * OSD_paint_spectrum() *	Paint the "spectrum level" at specified frequency. * * Inputs: *	px, py, py_old: pixel location of top of level/level_old. *	level, level_old: 0 =< value <= 23 * * *         X   *   +------> *   |       (px,py) *   |          +--------------------------+     --- * Y |          |       sp_color[i]        |      ^ *   V          +--------------------------+      | *                                                | *              +--------------------------+      | *              |       sp_color[i]        |      | *              +--------------------------+      | *                                                |       *              ~                          ~   height (based on level) *              ~                          ~      | *                                                | *              +--------------------------+      | *              |       sp_color[i]        |      | *              +--------------------------+      | *                                                | *              +--------------------------+      | *              |       sp_color[i]        |      v *              +--------------------------+     --- *                                          *              |<------ 22 pixels-------->| * */void OSD_paint_spectrum(int px, int py, int py_old, int level, int level_old){    int i, limit;    ushort sp_color[] = {0xaaaa,0x5555};        if (level < level_old) {	/* clear old level */	OSD_paint_rect(px, py_old, 22, 2*(level_old-level), 0);    } else {	for (i=level; i >= level_old ; i--, py+=2) {	    OSD_paint_rect(px, py, 22, 1, sp_color[i>>4]);	}    }}#endif EQUALIZER

⌨️ 快捷键说明

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