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 + -
显示快捷键?