📄 osdcore.c
字号:
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)osdcore.c 1.27 6/3/98 *//* * $Log$ */#include "common.h"#include "const.h"#include "display.h"#include "fsosd.h"#include "util.h"#include "mvd.h"#include "vcd.h"#define EPRINTF(a) #ifdef OSD_COMPRESSextern void OSD_decompression (int, unsigned char *, unsigned char *, unsigned char *, unsigned short *, int);#endif /* OSD_COMPRESS *//* * 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. *//* * 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))#ifdef CUST4 && !OSD_msg_override#endif ) { 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)];#ifdef CUST4 if (clean_up == OSD_BLINKING && OSD_blink_region == region) /* Show blinking message */ osd_new = OSD_blink_msg; else #endif osd_new = OSD_new; }#ifndef BF43 if (mineomine && (region_mask & (OSD_LINE_2_MASK|OSD_LINE_3_MASK|OSD_LINE_4_MASK|OSD_LINE_5_MASK))) { if (region_mask & (OSD_LINE_2_MASK|OSD_LINE_3_MASK)) { if (region_mask & OSD_LINE_3_MASK) region -= OSD_REGIONS_PER_LINE; /* Set early so that the current OSD dma won't output * our new OSD data to the wrong location on the screen. * * NOTE: restricted OSD only occurs for PAL output */ mvd[vid_scn_osd_vend] = (OSD_PAL_VERT_POS1 + 2*OSD_CHAR_HEIGHT/2 -1) + osd_adjust_vstart; } else { if (region_mask & OSD_LINE_4_MASK) { region -= 2*OSD_REGIONS_PER_LINE; } else { /* region in OSD LINE_5 */ region -= 3*OSD_REGIONS_PER_LINE; } /* Set early so that the current OSD dma won't output * our new OSD data to the wrong location on the screen. * * NOTE: restricted OSD only occurs for PAL output */ if ((OSD_total_areas == 2)) mvd[vid_scn_osd_vstart] = vid_scn_osd_vstart2 + osd_adjust_vstart; } } #endif /* not BF43 */ /* * 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_DRAM_START + OSD_LINE_NUM(region) * OSD_DRAM_DX*OSD_MAX_CHAR/2 * OSD_CHAR_HEIGHT/2) << 2; for (count = 0; offset < end; ) { unsigned int ctmp = osd_new[count]; big = (ctmp >= FONT_CSTART); if (current[pos] != ctmp) { /* Starting data offset (in byte); i.e. head+offset*6 */ dest = head + (offset << 2) + (offset << 1); OSD_copy_one_char(ctmp, big, dest, OSD_DRAM_DX*(OSD_MAX_CHAR/2)); current[pos] = ctmp; } count++; pos++; offset++; if (big) { current[pos] = ctmp; /* 'big' uses 2 char positions */ 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) */#ifdef OSD_COMPRESS int new = 1; /* A new character */ unsigned char scratch_buf[24]; /* To store decompressed data */ unsigned short *bufend = (unsigned short *) &scratch_buf[24];#endif /* * Look up from small (English) font or big (Chinese) font * table? */#ifdef OSD_COMPRESS /* * For compressed data, "small" & "big" are contained in the same table. * * Set ctmp to the offset of T_osd_offset_tbl. */#ifdef CUST71 if (ctmp > FONT_KEYSCALE) ctmp-=1;#ifndef CUST_SPATIAL if (ctmp > FONT_3D1A) ctmp-=2;#endif#endif ctmp -= FONT_START;#else if (ctmp < FONT_CSTART) { tmp = ctmp - FONT_START; tmp *= (OSD_CHAR_HEIGHT/2) * OSD_SM_WIDTH; srcptr = &osd_font[tmp]; } else { tmp = ctmp - FONT_CSTART; tmp *= (OSD_CHAR_HEIGHT/2) * OSD_LG_WIDTH; srcptr = &osd_cfont[tmp]; }#endif /* OSD_COMPRESS */ /* * 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); #ifdef OSD_COMPRESS srcptr = bufend;#endif /* Write one small/big character at a time */ for (tmp = 0; tmp < (OSD_CHAR_HEIGHT/2); tmp++) {#ifdef OSD_COMPRESS if (srcptr >= bufend) { /* Decompress 24B into scratch_buf */ OSD_decompression(ctmp, scratch_buf, T_osd_code_book, T_osd_comp_font, T_osd_offset_tbl, new); srcptr = (unsigned short *)scratch_buf; new = 0; /* Next 24B are no longer from a new character */ }#endif /* OSD_COMPRESS */ 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(void){ int i, j;#ifndef BF43 if (mineomine) dram_clear(OSD_DRAM_START, OSD_RESTRICTED_SIZE); /* 2 OSD-lines */ else#endif /* not BF43 */ { dram_clear(OSD_DRAM_START, OSD_DRAM_SIZE); } /* 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_displayed_regions = OSD_scheduled_regions = OSD_update_regions = OSD_suppressed_regions = 0;#ifdef CUST4 OSD_blink_region = OSD_blink_time = 0;#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -