📄 osd.c
字号:
/* Copyright 1997, ESS Technology, Inc. *//* SCCSID @(#)osd.c 4.5 10/17/03 *//* * $Log$ */#include "common.h"#include "mvd.h"#include "debug.h"#include "memmap.h"#include "vcxi.h"#include "const.h"#include "util.h"#include "sysinfo.h"#include "osd.h"#include "low.h"#include "echo.h"#include "dsa.h"#include "cg.h"/*#include "cust.h"*/#define YPRINTF(a) EPRINTF(a)#define CPRINTF(a) #define OSD_MAX_WINDOWS 4/************************************************************************ static varibles*************************************************************************/typedef struct { int xstart; int xend; int xsize; /* by DOWRDs */ int ystart; int yend; int ysize; /* by lines for a field */ int addr0; /* field 0 starting address */#ifndef PROG_OSD int addr1; /* field 1 starting address */#endif} OSD_WINDOW;static OSD_WINDOW osd_canvas;static OSD_WINDOW osd_act[OSD_MAX_WINDOWS];static int osd_vsize;static int osd_pixel_mode = 2;static int osd_bits_per_pixel;static int pixels_per_dword;static int pixels_per_byte;static int osd_on_keep;static int osd_windows;static int osd_cur_window;static int osd_voffset;static int osd_hoffset = 0;static int osd_bug;static int osd_bug_patch;static int osd_dw_cell = 0x55555555;static int OSD_START0;static int OSD_START1;static uchar osd_byte_cell = 0;static int osd_suspend = 0;#ifdef SCR_SAVERstatic OSD_WINDOW osaver;static int osd_setup_saver=0;#endif/************************************************************************ Palette default setting.*************************************************************************/short osd_palette[16] = { (OSD_CLEAR | 0x0), (OSD_BLACK | 0xb), (OSD_DARK | 0xf), (OSD_BRIGHT | 0xf), (OSD_LIGHTPINK | 0xf), (OSD_LIGHTORANGE | 0xd), (OSD_LIGHTGREEN | 0xe), (OSD_BLACK | 0xf), (OSD_YELLOW | 0xf), (OSD_YELLOW | 0xf), (OSD_LIGHTBLUE | 0xc), (OSD_BLACK | 0xf), (OSD_LIGHTBLUE | 0xa), (OSD_BROWN | 0xf), (OSD_CYAN | 0xf), (OSD_GRAY | 0xf)}; /************************************************************************ static functions*************************************************************************/static int osd_copy_data(int dwords, int dx_in_bytes, int dy, int xstart_offset, int xend_offset, uchar *addr, int dest, int mode);static int osd_bitblt (int x, int y, int dx, int dy, uchar *addr, int mode);#ifdef SCR_SAVERstatic int osd_saver_setup(int field);#endifstatic void osd_clear_mem(int addr0, int addr1, int size);static uchar osd_load_palette;/************************************************************************ clear osd area with 0*************************************************************************/static void osd_clear_mem(int addr0, int addr1, int size){ if (addr0 == 0) return; /* clear the whole canvas */ dram_clear(addr0, size); if (addr1 != 0) dram_clear(addr1, size);}/************************************************************************ OSD initialization*************************************************************************/void OSD_init(int x, int y, int dx, int dy, int bits_per_pixel, int f0, int f1, int mode, int reset){ int tmp; OSD_WINDOW *pw = &osd_canvas;#ifdef SCR_SAVER if (mode) pw = &osaver;#endif switch ( bits_per_pixel) { case 0: osd_pixel_mode = 0; osd_bug_patch = 0; break; case 2: osd_pixel_mode = 1; osd_bug_patch = 0x3fffffff; break; case 4: osd_pixel_mode = 2; osd_bug_patch = x0fffffff; break; case 8: osd_pixel_mode = 3; osd_bug_patch = x00ffffff; break; default: assert(0); break; } osd_bits_per_pixel = bits_per_pixel; pixels_per_dword = 32 / bits_per_pixel; pixels_per_byte = pixels_per_dword>>2; pw->xstart = x; pw->xend = x + dx; pw->ystart = y; pw->yend = y + dy - 1; pw->ysize = dy / 2; /* for each field */ tmp = osd_bits_per_pixel * dx; pw->xsize = (tmp+31)/32; /* by DWORD */ assert(pw->xsize > 0); assert(pw->ysize > 0); pw->addr0 = OSD_START0 = f0;#ifndef PROG_OSD pw->addr1 = OSD_START1 = f1;#endif if (reset) { osd_clear_mem(pw->addr0, pw->addr1, pw->xsize*pw->ysize); if (reset > 1) { osd_windows = osd_vsize = 0; mvd[vid_scn_osd_palette] = (OSD_CLEAR | 0x0); } } if (power_up) { OSD_clear(); /* initialize various OSD registers */ mvd[vid_scn_osd_misc] = osd_pixel_mode; mvd[vid_scn_osd_hstart] = x + osd_hoffset; mvd[vid_scn_osd_hend] = x + dx + osd_hoffset; mvd[vid_scn_osd_vstart] = y; mvd[vid_scn_osd_vend] = y + dy - 1; } else {#ifdef SCR_SAVER if (!mode)#endif OSD_clear_all(1); /* clears CG status variables as well */ }}/************************************************************************ Function: Description:*************************************************************************/void OSD_clear(){ /* clear the whole canvas */ #ifdef PROG_OSD dram_clear(osd_canvas.addr0, 2*osd_canvas.xsize * osd_canvas.ysize);#else dram_clear(osd_canvas.addr0, osd_canvas.xsize * osd_canvas.ysize); dram_clear(osd_canvas.addr1, osd_canvas.xsize * osd_canvas.ysize); #endif}/************************************************************************ Setup palette, if load is 1, load it to system immediately.*************************************************************************/int OSD_set_palette(int index, int color, int load){#ifdef C256 if (index > 255) {#else if (index > 15) {#endif EPRINTF(("Out of palette \n")); return -1; } osd_palette[index] = color; osd_load_palette = load; return 0;}/************************************************************************ Set OSD active window *************************************************************************/int OSD_set_window(int x, int y, int dx, int dy){ int xstart, xend; int good_xstart, good_xend; int xstart_offset, xend_offset; int i; CPRINTF(("The window you are setting is ")); CPRINTF(("x=%d y=%d dx=%d dy=%d\n", x, y, dx, dy)); if (osd_windows == OSD_MAX_WINDOWS) { EPRINTF(("No more windows\n")); return 0; } if( x < osd_canvas.xstart || (dx + x) > osd_canvas.xend || y < osd_canvas.ystart || (dy + y - 1) > osd_canvas.yend ) { /* out of canvas */ EPRINTF(("The window you set is out of canvas!\n")); return -1; } xstart = x; xend = xstart + dx - 1; CPRINTF(("1: xstart = %d xend = %d \n", xstart, xend)); /* Since the region does not start/end at DWORD boundary, we have to enlarge it before using */ xstart_offset = (xstart - osd_canvas.xstart) % pixels_per_dword; xend_offset = (xend - osd_canvas.xstart + 1) % pixels_per_dword; if ( xend_offset ) xend_offset = pixels_per_dword - xend_offset; good_xstart = xstart - xstart_offset; good_xend = xend + xend_offset; CPRINTF(("2: good_xstart = %d good_xend = %d \n", good_xstart, good_xend)); osd_windows++; /* OSD settings */ osd_act[osd_windows - 1].xstart = good_xstart; osd_act[osd_windows - 1].xend = good_xend + 1; osd_act[osd_windows - 1].ystart = y; osd_act[osd_windows - 1].yend = y + dy - 1 ; osd_act[osd_windows - 1].ysize = dy / 2; osd_act[osd_windows - 1].xsize = osd_canvas.xsize; osd_act[osd_windows - 1].addr0 = OSD_START0 + osd_vsize * osd_canvas.xsize;#ifndef PROG_OSD osd_act[osd_windows - 1].addr1 = OSD_START1 + osd_vsize * osd_canvas.xsize; #endif assert(osd_act[osd_windows - 1].xsize > 0); assert(osd_act[osd_windows - 1].ysize > 0); osd_vsize += dy / 2; /* clear memory */#ifdef PROG_OSD dram_clear(osd_act[osd_windows - 1].addr0, 2 * osd_act[osd_windows - 1].xsize * osd_act[osd_windows - 1].ysize);#else dram_clear(osd_act[osd_windows - 1].addr0, osd_act[osd_windows - 1].xsize * osd_act[osd_windows - 1].ysize); dram_clear(osd_act[osd_windows - 1].addr1, osd_act[osd_windows - 1].xsize * osd_act[osd_windows - 1].ysize);#endif osd_load_palette = 1; CPRINTF(("xstart = %d \n", osd_act[osd_windows - 1].xstart)); CPRINTF(("xend = %d \n", osd_act[osd_windows - 1].xend)); CPRINTF(("ystart = %d \n", osd_act[osd_windows - 1].ystart)); CPRINTF(("xend = %d \n", osd_act[osd_windows - 1].yend)); CPRINTF(("xsize = %d \n", osd_act[osd_windows - 1].xsize)); CPRINTF(("ysize = %d \n", osd_act[osd_windows - 1].ysize)); CPRINTF(("add0 = %d \n", osd_act[osd_windows - 1].addr0));#ifndef PROG_OSD CPRINTF(("add1 = %d \n", osd_act[osd_windows - 1].addr1));#endif return 0;} /************************************************************************ OSD on/off*************************************************************************/int OSD_on (int on) { if (on) osd_on = 1; else osd_on = 0; return osd_on;} /************************************************************************ Keep the current OSD on/off status.*************************************************************************/void OSD_save_on(){ osd_on_keep = osd_on;}/************************************************************************ Restore the current OSD on/off status.*************************************************************************/void OSD_restore_on(){ osd_on = osd_on_keep;}void OSD_suspend(){ osd_suspend = 1;}void OSD_resume(){ osd_suspend = 0;}/************************************************************************ Set up the OSD.************************************************************************/int org_osd_startstop = (5<<12)+(0x23<<6)+0x20;void OSD_setup(int field){ int ystart, ysize; int addr; OSD_WINDOW *cur; if (osd_load_palette) { int i; mvd[vid_scn_osd_misc] = 0x4;#ifdef C256 for (i=0; i<256; i++)#else for(i = 0; i < 16; i++)#endif mvd[vid_scn_osd_palette + i] = osd_palette[i]; osd_load_palette = 0; mvd[vid_scn_osd_misc] = osd_pixel_mode; }#ifdef SCR_SAVER if (osd_saver_setup(field)) return;#endif if (osd_suspend || !osd_on || !osd_windows) { /* We don't have any osd to be displayed */ mvd[vid_scn_osd_misc] = osd_pixel_mode; buscon_xfer(ysn, BDMA_USEDX, PCM_zero_start, 1, 1); return; } if (field != -1) { osd_cur_window = 1; } else { osd_cur_window++; } cur = (OSD_WINDOW *) &osd_act[osd_cur_window -1]; /* Set region */ mvd[vid_scn_osd_hstart] = cur->xstart + osd_hoffset; mvd[vid_scn_osd_hend] = cur->xend + osd_hoffset; ystart = (cur->ystart + osd_voffset) >> 1; #ifdef PROSCAN ystart <<= vcx_tv_mode;#endif mvd[vid_scn_osd_vstart] = ystart; ysize = cur->ysize;#ifdef PROSCAN ysize <<= vcx_tv_mode;#endif if (osd_windows > 1) { mvd[vid_scn_osd_vend] = (ystart + ysize) - 1; } else { mvd[vid_scn_osd_vend] = (ystart + ysize) - 2; } /* OSD DMA */ if (osd_cur_window == 1) {#ifdef PROSCAN org_osd_startstop = (vcx_tv_mode) ? 0xe20 : (5<<12)+(0x23<<6)+0x20;#endif mvd[vid_scn_osd_startstop] = org_osd_startstop;#ifdef PROG_OSD mvd[buscon_dma_width0] = osd_act[0].xsize; addr = OSD_START0;#ifdef PROSCAN if (vcx_tv_mode) { buscon_xfer(ysn, BDMA_WIDTH0|BDMA_INC1, addr, osd_act[0].xsize, 0); } else#endif { if (field) addr += osd_act[0].xsize; buscon_xfer(ysn, BDMA_WIDTH0|BDMA_INC2, addr, osd_act[0].xsize, 0); }#else addr = (field) ? OSD_START0 : OSD_START1; buscon_xfer(ysn, BDMA_USEDX, addr, osd_vsize, osd_act[0].xsize);#endif } if (osd_cur_window < osd_windows) { mvd[vid_scn_osd_misc] = osd_pixel_mode | 0x8; } else { mvd[vid_scn_osd_misc] = osd_pixel_mode; } return;}/***************************************************************************** Vertical shift *****************************************************************************/void OSD_vertical_shift(int offset){ osd_voffset = offset;}/***************************************************************************** Horizontal shift *****************************************************************************/void OSD_horizontal_shift(int offset){ osd_hoffset = offset;}/***************************************************************************** Paint a dot. *****************************************************************************/void OSD_dot(int x, int y, int color){ uint t, *p, s, m; x -= osd_canvas.xstart; if (x==0) return; y -= osd_canvas.ystart;#ifdef PROG_OSD t = OSD_START0 + (y*osd_canvas.xsize) + #ifdef C256 (x>>2);#else (x/8);#endif#else t = (y&1) ? OSD_START1 : OSD_START0; t += (y/2*osd_canvas.xsize) + (x/8);#endif p = (uint *)dram(t);#ifdef C256 s = 8*(4-(x&3)); t = *p; m = 0xff<<s;#else s = 4*(7-(x%8)); t = *p; m = 0xf<<s;#endif *p = (t & ~m) | (color << s);#ifdef ECHO MIC_service();#endif}/***************************************************************************** Draw a line. *****************************************************************************/void OSD_line(int x0, int y0, int x1, int y1, int color){ int d, x, y, dx, dy, sx, sy; dx = x1 - x0; if (dx<0) { dx = (-dx)<<1; sx = -1; } else { dx = dx<<1; sx = 1; } dy = y1 - y0; if (dy<0) { dy = (-dy)<<1; sy = -1; } else { dy = dy<<1; sy = 1; } x = x0; y = y0; if (dx > dy) { d = dy - (dx>>1); while (1) { OSD_dot(x, y, color); if (x==x1) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -