zoom.c

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

C
656
字号
/* Copyright 1997, ESS Technology, Inc.					*//* SCCSID @(#)zoom.c	1.59 2/17/98 *//* * $Log$ */#ifdef ZOOM#include "mvd.h"#include "common.h"#include "util.h"#include "debug.h"#include "display.h"#include "zoom.h"#include "buffer.h"#include "fsosd.h"#include "vp.h"#include "vcxi.h"#include "play.h"#ifdef VSCALE#include "vscale.h"#endif#ifdef CUST3#include "const.h"#include "custdsa.h"#endif#include "xport.h"static unsigned int U_zoom_start , V_zoom_start, Y_zoom_start;int save_width1;int FromBtoB;static int zoom_y_offset, zoom_uv_offset;static unsigned int disp_width, disp_height;PRIVATE void get_pic_size(void);#ifdef PLAY20extern int play_state;#endif#ifndef BF43static int UV_location=-1;#endifvoid Zoom_start(){    int       i, j, k, m, tmp;    int       dest_u_start, dest_v_start, dest_y_start;    int       wY, wUV;    DISP_Info *dip, *dipp;    unsigned  int buffer_size, height;    extern int DISP_frame;    int compressed = 0;    int       v_start, u_start, y_start;    int       width, full_height;    extern int scale_dy_Y, scale_dy_UV;    FromBtoB = 0;    dip = DISP_info + DISP_frame;    full_height = dip->height > 288;    wY  = dip->wY;    wUV = dip->wUV;    if (!zoom_y_pos) zoom_y_pos = 2;    k = (zoom_y_pos-2)*wY;    if (full_height || dip->zUV) {   /* E2  or  E0 with compressing */	zoom_uv_offset = ((zoom_y_pos-2) * wUV + ((zoom_x_pos * 3) >> 4))>>1;	zoom_uv_offset = (zoom_uv_offset+1) / 3 * 3;	tmp = zoom_uv_offset % wUV;	m = zoom_uv_offset - tmp;	if (full_height) {	    mvd[vid_scn_misc0] &= 0xfffffffe;	    mvd[vid_scn_misc0] |= 0x6000;	    zoom_y_offset = (m << 2) + (tmp << 1);	} else {	    if (dip->zY)		zoom_y_offset = k + (tmp << 1);	    else {		zoom_y_offset = (zoom_uv_offset/wUV * wY) << 1;		zoom_y_offset += ((tmp << 2)/3) << 1;	    }	}    }    else {               /* E0 without compressing */        zoom_y_offset = k + (zoom_x_pos >> 2);        zoom_uv_offset = ((k + (zoom_x_pos >> 1)) >> 2);    }    zoom_y_offset &= 0xfffffffe;    zoom_uv_offset += zoom_uv_offset/wUV*wUV;  /* this is because U, V buffer 	is looked like uuuu..vvvv...uuu...vvv.. */#ifndef BF43    if (UV_location!=-1) {        if (zoom_y_pos) {        i = zoom_y_pos/scale_dy_Y * scale_dy_Y;        }        else        i = 0;        zoom_y_offset -= i*wY;        zoom_uv_offset-= ((i>>1)<<1) * wUV ;    }#endif    /* When E0 zoom by 2, or E2 zoom by 4, hardware cannot do vscale       as Y,U,V wholely. So, we let hardware do Y vscale, and duplicate       UV ourselfs by store UV to a temperary buffer, and duplicate the       line .       We use VBV buffer as temperary buffer to store U and V, with       duplicated lines.      */    if (zoom_level == 2 || !dip->zY || DISP_frame == 2) {#ifndef BF43	/* duplicated copy line */	if(UV_location==-1)          u_start = dip->startU + zoom_uv_offset;   /* dword address */	else          u_start = UV_location + zoom_uv_offset;   /* dword address */#else        u_start = dip->startU + zoom_uv_offset;   /* dword address */#endif        v_start = u_start + dip->wUV;   	  /* dword address */		/* width of each line which needed to be duplicated */        if (zoom_level == 1)                 /* E0 */#ifndef BF43	  if (mineomine) width = 21;	  else#endif	    width = (wUV + 1) >> 1;        else                                 /* E2 */	    width = (wUV + 3) >> 2;	height = dip->height >> 2;	buffer_size = ((height * width) << 1);		zoom_frame = -1;	switch (DISP_frame) {	  case 0:	  case 1:	    dipp = DISP_info + 2;	    U_zoom_start = dipp->startY;	    break;	  case 2:	    zoom_frame = H_VscaleFrame;            if (vcx_scn_vscale != 0x10 #ifdef PLAY20		&& play_state != PLAY_STILL_STATE		&& play_state != PLAY_WAIT_TIME_STATE		&& !is_slide_show#endif	    ) {		FromBtoB=1;                dipp = DISP_info + 2;	    }            else 	    {#ifdef VSCALE	    if (H_VscaleFrame == 1)		dipp = DISP_info + 1;	    else		dipp = DISP_info + 0;#else	    dipp = DISP_info + 0;#endif	    }        if (zoom_y_pos >= 76)            U_zoom_start = dipp->startY;        else            U_zoom_start = dipp->startU - buffer_size * 2 ;#ifndef BF43	if (UV_location!=-1)            U_zoom_start = (dipp->startU+dipp->height*dipp->wUV) -(buffer_size<<1) ;#endif            break;	  default:	    U_zoom_start = VBV_start;     /* E2 picture, zoom_buffer start */	    				  /* at VBV buffer */	    break;	}	V_zoom_start = U_zoom_start + buffer_size;	j = 0; m=0;	k = (width *3 ) >> 2;	for (i = 0; i < (dip->height >> 2); i++) {	    m = (i * wUV ) << 1;	    {		for (k = 0; k < width; k++) {		    *(long*) dram(j + width + U_zoom_start) =			*(long*) dram(j + U_zoom_start) = 			    *(long*)dram(u_start + m);		    *(long*) dram(j + width + V_zoom_start) =			*(long*) dram(j + V_zoom_start) = 			    *(long*)dram(v_start + m);		    j++; m++;		    asm("nop");		    asm("nop");		}		j +=  width;	    }	}    }#ifndef BF43    if (UV_location!=-1) {        wY = dipp->wY;	width <<=1;	height = dipp->height>>1;        Y_zoom_start = U_zoom_start - height*width;        m = Y_zoom_start;        u_start = dipp->startY + zoom_y_offset;   /* dword address */        for (j=0;j<height;j++) {          for (i=0;i<width;i++) {             *(long*)dram(m)=*(long*)dram(u_start);             m++; u_start++;          }          u_start += wY-width;        }    }#endif    /* with VSCALE on, we cannot use DMA_WIDTH2 register , always set       DMA_WIDTH0 to 0, and DMA_WIDTH1 to real width.      */    DISP_change_zoom(zoom_level);    if (zoom_level == 1 && !full_height)        mvd[buscon_dma_width1] = wY >> 1;}void zoom_reset(){    extern int disp_frame;    extern int save_zoom_level;    DO_blank();    zoom_x_pos = 0;    zoom_y_pos = 0;    mvd[buscon_dma_scale_type] = 0;    mvd[buscon_dma_width1] = save_width1;    zoom_level = 0;    DISP_change_zoom(zoom_level);    if (vcx_scn_vscale != 0x10 && DISP_frame==2 && FromBtoB) {         rescaleB();    }    disp_frame = DISP_frame;}rescaleB(){	resetVscale();        initVscale_Pointer();        VscaleStart = 1;        VscaleLastFrame = 0;        while (VscaleStart) vscale2();}void zoom_in(void){    extern int VID_decoding_in_progress ;/*  If system is not really pause, then ignore zoom_in key */#ifdef PLAY20    if (XPORT_active && play_state == PLAY_NORMAL_STATE)        return;#endif    get_pic_size();#if (!CUST71 && !CUSTDVD) /* For CUST71, this is handled in play.c */    if (disp_height <= 288#ifdef PLAY20	|| is_slide_show#endif	) {	/* For low resolution, only do 2X zoom */	if (zoom_level == 1)	    return;	zoom_level = 1;    }    else  #endif	/* CUST71 */    {	if (zoom_level == 2)	    return;	zoom_level ++;    }    if (zoom_level == 1) {	zoom_x_pos += disp_width >> 2;	zoom_y_pos += disp_height >> 2;    } else    if (zoom_level == 2) {	zoom_x_pos += disp_width >> 3;	zoom_y_pos += disp_height >> 3;    }    save_width1 = mvd[buscon_dma_width1] ;    DO_blank();#ifndef BF43    UV_location=-1;    if (DISP_frame == 2 && vcx_scn_height == 288#ifdef PLAY20                && play_state != PLAY_STILL_STATE                && play_state != PLAY_WAIT_TIME_STATE                && !is_slide_show#endif	    ) {           Adjust_zoom_XY(zoom_x_pos, zoom_y_pos);           scale_half();           Zoom_start();	   return;    }#endif    pan(zoom_x_pos, zoom_y_pos);    return;}void zoom_move_right(){    zoom_x_pos += HORZ_OFFSET;    pan(zoom_x_pos, zoom_y_pos);}void zoom_move_left(){    zoom_x_pos -= HORZ_OFFSET;    pan(zoom_x_pos, zoom_y_pos);}void zoom_move_up(){#ifndef BF43    if (DISP_frame == 2 && vcx_scn_height == 288#ifdef PLAY20                && play_state != PLAY_STILL_STATE                && play_state != PLAY_WAIT_TIME_STATE                && !is_slide_show#endif	) {        zoom_y_pos -= VERT_OFFSET;        Adjust_zoom_XY(zoom_x_pos, zoom_y_pos);        scale_half();        Zoom_start();	return;    }#endif    if ((DISP_frame == 2 && vcx_scn_vscale !=0x10) 	&& (zoom_y_pos >= 76 && zoom_y_pos - VERT_OFFSET<76)) {	DO_blank();        zoom_reset_scale(1);	pan(zoom_x_pos, zoom_y_pos);    } else {        zoom_y_pos -= VERT_OFFSET;	pan(zoom_x_pos, zoom_y_pos);    }}void zoom_move_down(){#ifndef BF43    if (DISP_frame == 2 && vcx_scn_height == 288#ifdef PLAY20                && play_state != PLAY_STILL_STATE                && play_state != PLAY_WAIT_TIME_STATE                && !is_slide_show#endif	) {           zoom_y_pos += VERT_OFFSET;           Adjust_zoom_XY(zoom_x_pos, zoom_y_pos);           scale_half();           Zoom_start();	   return;    }#endif    if ((DISP_frame == 2 && vcx_scn_vscale !=0x10) &&        (zoom_y_pos < 76 && zoom_y_pos + VERT_OFFSET>=76)) {	DO_blank();        zoom_reset_scale(0);	pan(zoom_x_pos, zoom_y_pos);    } else {        zoom_y_pos += VERT_OFFSET;	pan(zoom_x_pos, zoom_y_pos);    }}zoom_reset_scale(int up){    int x, y;    x = zoom_x_pos;    if (up)    zoom_y_pos -= VERT_OFFSET;    else    zoom_y_pos += VERT_OFFSET;    y = zoom_y_pos;    zoom_reset();    zoom_x_pos = x;    zoom_y_pos = y;    zoom_level = 1;}#ifndef BF43scale_half(){        DISP_Info *curr_dip;	int i,j;	extern int scale_mb_from_Y, scale_mb_from_UV,           scale_mb_to_Y, scale_mb_to_UV,           scale_mb_del_Y, scale_mb_del_UV,           scale_line_del_Y, scale_line_del_UV;	extern int scale_dy_Y, scale_dy_UV,           scale_zY, scale_zUV;         resetVscale();        initVscale_Pointer();        VscaleStart = 1;        VscaleLastFrame = 0;        curr_dip = DISP_info + H_VscaleFrame;        i = zoom_y_pos/scale_dy_Y * 16;        scale_mb_from_Y = i * curr_dip->wY + curr_dip->startY;        scale_mb_from_UV = i * curr_dip->wUV +curr_dip->startU;        curr_dip = DISP_info + H_B1FRAME;        i=(curr_dip->height==288)?10:8;        scale_mb_to_Y = curr_dip->startY;        scale_mb_to_UV = i*scale_dy_Y*curr_dip->wY+curr_dip->startY;        UV_location = scale_mb_to_UV;        for (j = 0; j<i; j++) {            vscale2();        }        resetVscale();}#endif#ifdef CUST3void zoom_center(){    if (!zoom_level)	return;    get_pic_size();    /* zoom_level == 1 */    zoom_x_pos = disp_width >> 2;    /* zoom_level == 2 */    zoom_y_pos = disp_height >> 2;    if (zoom_level > 1) {	zoom_x_pos += disp_width >> 3;	zoom_y_pos += disp_height >> 3;    }    pan(zoom_x_pos, zoom_y_pos);}#endif#if (!CUST3 || CUST71 || CUSTDVD)void zoom_out(){    if (!zoom_level)	return;    zoom_level --;    get_pic_size();    if (zoom_level == 1) {	zoom_x_pos -= disp_width >> 3;	zoom_y_pos -= disp_height >> 3;    }    DO_blank();    if (!zoom_level) {	expect_zoom = 0;        zoom_reset();        if (vcx_scn_vscale != 0x10 && DISP_frame==2 && FromBtoB) {             rescaleB();        }    }    else {        save_width1 = mvd[buscon_dma_width1] ;        pan(zoom_x_pos, zoom_y_pos);    }}#endifpan(int x, int y){    Adjust_zoom_XY(x, y);    Zoom_start();}Adjust_zoom_XY(int x, int y){    get_pic_size();     if (x < 0) x = 0;    if (y < 0) y = 0;     {        int width  = disp_width >> 1;        int height = disp_height >> 1;             if (zoom_level == 2) {            width  = (width * 3) >> 1;            height = (height * 3) >> 1;        }             if (x > width) x = width;        if (y > height) y = height;    }     /* zoom_x_pos needs to think of compressed picture or not(3/4), so we       must make sure each picture begin at boundary of dword */#if 0    zoom_x_pos = x / 12 * 12;#else    zoom_x_pos = x ;#endif    zoom_y_pos = y & 0xfffffffe;}void Buscon_zoom(DISP_Info *dip){    int y_start, u_start, v_start;    int full_height;    int wY, wUV, zY, zUV;    wY  = dip->wY;    wUV = dip->wUV;    y_start = dip->startY + zoom_y_offset;    u_start = dip->startU + zoom_uv_offset;    v_start = u_start + wUV;    zY  = dip->zY;    zUV = dip->zUV;    full_height = dip->height > 288;    if (zoom_level == 1) {#ifdef BF43	if (zUV < 0) zUV = 0;	if (zY < 0) {	  mvd[buscon_dma_deltas_ysc] = 0x200 - (wUV+1); /* y_wordsize = uv_wordsize*2-1 */	  zY = 0;	}	else#else	if (mineomine) {	    wY = 82;	    wUV = 41;	}#endif	mvd[buscon_dma_deltas_ysc] = 0x200 - ((wY + 1) >> 1);	{	    	    mvd[buscon_dma_deltas_usc] = 0x200 - ((wUV + 1) >> 1);	    mvd[buscon_dma_deltas_vsc] = 0x200 - ((wUV + 1) >> 1);	}	if (full_height) {	    buscon_quick_BF(ysc, y_start, BDMA_WIDTH2, zY);	    buscon_quick_BF(usc, u_start, BDMA_WIDTH1|BDMA_INC2, zUV);	    buscon_quick_BF(vsc, v_start, BDMA_WIDTH1|BDMA_INC2, zUV);	}	else {#ifndef BF43        if (UV_location!=-1){            buscon_quick_BF(ysc, Y_zoom_start, BDMA_USEDX, zY);        }	else#endif	    buscon_quick_BF(ysc, y_start, BDMA_WIDTH1 | BDMA_INC2, zY);	    buscon_quick_BF(usc, U_zoom_start, BDMA_USEDX, zUV);	    buscon_quick_BF(vsc, V_zoom_start, BDMA_USEDX, zUV);	}    }    else  {  /* zoom_level == 2 */	mvd[buscon_dma_deltas_ysc] = 0x200 - ((wY + 3) >> 2);	mvd[buscon_dma_deltas_usc] = 0x200 - ((wUV + 3) >> 2);	mvd[buscon_dma_deltas_vsc] = 0x200 - ((wUV + 3) >> 2);		buscon_quick_BF(ysc, y_start, BDMA_WIDTH2|BDMA_INC2, zY);	buscon_quick_BF(usc, U_zoom_start, BDMA_USEDX, zUV);	buscon_quick_BF(vsc, V_zoom_start, BDMA_USEDX, zUV);	    }}/* * Get picture width and height */void get_pic_size(){    DISP_Info *dip;    extern int DISP_frame;        dip = DISP_info + DISP_frame;    if (dip->zY)	disp_width = ((dip->wY << 2) / 3 ) << 2;     else	disp_width = dip->wY << 2;     disp_height = dip->height;}DO_blank(){    done_blank = 0;    do_blank ++;       /* Display a tiny screen to blank screen   */    /*     * We'll wait here for up to 1/60th of a second until the     * screen is blanked out. During this period of time, I want to     * continue my communication with DSA and the external     * microprocessor     */    do {#if (!MVD_BOARD && !PLAYONLY)    receive_dsa();#endif    } while(!done_blank);    do_blank --;       /* Don't need to blank screen any more */}#ifdef PLAY20void set_zoom(){    if (!zoom_level) {        zoom_in();#ifdef CUST3#if (CUST71 || CUSTDVD)	OUTOSD(FUNCTION_REGION, MSG_zoom_in, MSG_zoom_in, 0);#else	OUTOSD(FUNCTION_REGION, MSG_e_zoomin, MSG_c_zoom, 0);#endif	/* CUST71 */#endif	/* CUST3 */    } else if (zoom_level == 1 &&	       play_state != PLAY_STILL_STATE &&	       vcx_user_video_stream == 0xe2) {        /* Only for high-resulotion, we have two level zoom */        zoom_in();    } else  {        zoom_reset();#ifdef CUST3    	OSD_clear_region(FUNCTION_REGION);#endif    }#ifdef CUST3    current_key = NO_KEY;#endif}#else/* For playonly machine */void set_zoom(){}#endif	/* else of PLAY20 */#endif	/* ZOOM */

⌨️ 快捷键说明

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