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

📄 po4tact.c

📁 一个不错的硬盘播放器程序,包含VFD显示程序,红外线遥控程序,硬盘读写程序,及解码程序等.
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    unsigned int endTimer;

    /* Give loader a chance to catch up */
    endTimer = glbTimer + EIGHTH_SECOND;
    do {
#ifdef ECHO
	MIC_service();
#endif
    } while (glbTimer < endTimer);

#ifdef JIANGHAI
    /*
     * There is no basis for gussing for CDDA data. We have to assume
     * that play is properly done!
     */
    if (TDM_isCDDA) {
	tdmStopCopy = 0;
	return(1);
    }
#endif

    if (detectState()) {
	/* We are indeed playing */
	tdmStopCopy = 0;	/* Start data copying			*/
	return(1);
    } return(0);
}

/*
 * Immediately swap from digest to normal (checked)
 */
PRIVATE void digest2Normal()
{
    /* 
     * If we are doing audio digest or there is no data, show logo.
     * Make the decision first since we may set XPORT_active to 0
     * inside quitDigest.
     */
    if (TDM_isCDDA || !XPORT_active) displayLogo = 1;

    if (vcx_digest) {
	quitDigest();
	showDarkBframe();
	DISP_change_resolution(352, vcx_VertSz);
    }
    scanMode = SCAN_OFF;
}

void IR_send_FB()
{
    /* If we are in the middle of REP AB, then we'll reset it */
    if (stRepAB == 2) stRepAB = 0;
    IR_send_data(IRKEY_FB, 0);
}

#if 0
void irSendFF()
{
    /* If we are in the middle of REP AB, then we'll reset it */
    if (stRepAB == 2) stRepAB = 0;
    IR_send_data(IRKEY_FF, 0);
}
#endif

void IR_send_Next()
{
    stRepAB = 0;
    IR_send_data(IRKEY_NEXT, 0);
}

void IR_send_Pause()
{
    IR_send_data(IRKEY_PAUSE, 0);
    /* 
     * We HAVE to assume that CD is paused. Otherwise, if we make a wrong
     * guess, we may send another PAUSE that leads to play.
     */
    tdmStopCopy = 1;
    playMode = MODE_PAUSE;
}

void IR_send_Play()
{
    delayQuarterSec();
    IR_send_data(IRKEY_PLAY, 0);

    if (!detectPlay()) {
	/* There is no harm to send another play key */
	delayQuarterSec();
	IR_send_data(IRKEY_PLAY, 0);
    }

    /* Let's assume that we are playing */
    tdmStopCopy = 0;
}

/*
 * Send a track selection number
 */
PRIVATE unsigned char irNumArray[] = {
    IRKEY_10, IRKEY_1, IRKEY_2, IRKEY_3, IRKEY_4,  IRKEY_5,
    IRKEY_6,  IRKEY_7, IRKEY_8, IRKEY_9, IRKEY_10, IRKEY_10PLUS
};
PRIVATE void irSendSelect(track)
int track;
{
    delayQuarterSec();
    delayQuarterSec();
    IR_send_data(irNumArray[track], 0);
}


/*
 * This routine resets mode variables. If a key gets you out of FB/FF/SLOW,
 * then this routine should be called to reset the play state and send
 * you back to PLAY state. From there, you can assign new state according
 * to the key.
 */
void resetMode()
{
    if (!vcx_digest) {
	/* 
	 * Don't do this if we are in digest (otherwise, when we make
	 * a selection after the 9th picture, we will end with audio
	 * clip.)
	 */
	vcx_playvideo_only	= 0;
	vcx_playaudio_only	= 0;
    }
    vcx_interupt_FrameCount	= 0;
    vcx_interupt_FrameCount_pause = 0;
    vcx_pause			= 0;
    vcx_pause_ack		= 0;
    vcx_slow_motion		= 0;
    playMode 			= MODE_NORMAL;
    nextNplay			= 0;

    /*
     * SCAN_A will clear vcx_fast_forward. Don't clear it here because
     * we may have FF/FB inside SCAN_A, we don't want to resent
     * vcx_fast_forward in that case.
     */
    if (scanMode != SCAN_A) 
      vcx_fast_forward = 0;

    CLEAROSD(OSD_PAUSE_REGION); /* clear just in case */
    CLEAROSD(OSD_VIEW_REGION);
}


/*
 * In addition to the old "resetMode", also clears the decoder core.
 */
void resetSystem()
{
    resetMode();
    cleanSystemState();
}

/*
 * At OPEN/CLOSE/STOP, all variables are reset
 */
PRIVATE void resetAll()
{
    resetSystem();
    TDM_setIsCDDA = 0;

    /* If we are in digest mode, then get out */
    vcx_fast_forward = 0;
    if (vcx_digest) quitDigest();
    scanMode = SCAN_OFF;
    stRep = 0;		/* Repeat 1/all is reset at open/close/stop	*/
    stRepAB = 0;	/* Repeat A to B is reset			*/
    stRem = 0;		/* Single/total remain is reset			*/
    cntTen = 0;		/* cntTen is cleared by STOP and OPEN/CLOSE	*/
    TDM_most_recent_video = 0;	/* So we can change logo if needed	*/
    /*
     * Assume incoming disk is 1.1 unless proven otherwise.
     */
    vcdVersion = 0x3131;
}

/*
 * Display the volume bar.
 *
 * Input:
 *	level:	an integer between AUDIO_MIN (0) and AUDIO_MAX (16).
 *	osdlen:	number of seconds to show this OSD
 */
PRIVATE unsigned char	volumebarbuf[12] = "           ";
PRIVATE void osdVolumeBar(level, osdlen)
int level;
int osdlen;
{
    int i, tmp = 0;

    if (level > 0) tmp = (level - 1) >> 1;

    for (i = tmp; i <= ((AUDIO_MAX - 1) >> 1); i++) {
	asm("nop");
	volumebarbuf[i] = FONT_SS;
    }

    for (i = 0; i < tmp; i++) {
	asm("nop");
	volumebarbuf[i] = FONT_LL;
    }

    if (level > 0) volumebarbuf[tmp] = ((level - 1) & 1) ? FONT_LL : FONT_LS;

    if (level <= 9) {
	volumebarbuf[AUDIO_BUFSZ - 3] = ' ';
    } else {
	level -= 10;
	volumebarbuf[AUDIO_BUFSZ - 3] = '1';
    }

    volumebarbuf[AUDIO_BUFSZ - 2] = '0' + level;
    OUTOSD(OSD_VOLUME_REGION, volumebarbuf, volumebarbuf, osdlen);
}

/************************************************************************
 * IR Key handling routines.						*
 ************************************************************************/
/*
 * This routine is called when 'A-B' key is pressed.
 *
 * CD can repeat from A to B (which is yet another mode of repeat)
 * This key clears the state of stRep.
 *
 * Variable stRepAB keeps track of currrent repeat A/B state
 *
 * This key has no other side effect.
 */
PRIVATE void procAB()
{
    /* Repeat AB clears Repeat 1/all */
    stRep = 0;


    /* 
     * Set A and Set B has to be apart by more than .25 second, else, 
     * some CD loader ignores Set B.
     */
    if (stRepAB == 0) timerSetA = glbTimer;
    else if (stRepAB == 1) {
	if ((glbTimer - timerSetA) < QUARTER_SECOND)
	  return;
    }

    stRepAB++;
    /*
     * Output 'SET A', 'REPEAT A to B' OSD only if we are not in VIEW/DIGEST
     */
    if (scanMode == SCAN_OFF) {
	if (stRepAB == 1) 
	  OUTOSD(OSD_FUNCTION_STATUS_REGION, MSG_set_A, MSG_c_set_A, 0);
	else if (stRepAB == 2) 
	  OUTOSD(OSD_FUNCTION_STATUS_REGION, MSG_repeatA2B, MSG_c_repeatA2B, 0);
	else OUTOSD(OSD_FUNCTION_STATUS_REGION, MSG_repeat_off, 
		    MSG_c_repeat_off, 5);
    }

    /* Limit the range of stRepAB to [0..2] */
    if (stRepAB > 2) stRepAB = 0;
}


#ifdef BROWSER1
/*
 * Switch to Browser on this button
 */
PRIVATE void procBrowser()
{
    unsigned int timer;

    /* Stop the CD */
    timer = glbTimer + EIGHTH_SECOND;
    do {
#ifdef ECHO
	MIC_service();
#endif
    } while (glbTimer < timer);
    IR_send_data(IRKEY_RETURN, 0);

    /*
     * Switch to browser. First kill all DMA stuff. Wait a bit just to
     * be on the safe side.
     */
    system_reset();
    timer = glbTimer + EIGHTH_SECOND;
    do {
#ifdef ECHO
	MIC_service();
#endif
    } while (glbTimer < timer);

    /* Browser starts at 0xc040000 */
    asm("addi    r0,#0x301,r22");
    asm("lsl     r22,r22,#16");
    asm("jspci   r22,#0,r0");
    asm("nop");
    asm("nop");
}
#endif

/*
 * This routine is called when FF/FB key is pressed.
 *
 * The logic is as follows:
 *	1) If we are in FAST mode, we'll quit it and enter normal play mode.
 *	2) If we are in PAUSE mode, then OSD shows 'FF'/'FB' momentarily
 *	   then back to PAUSE mode (some CD core will move things 
 *	   forward/backward when key is pressed, yet, it will be back
 *	   to pause when key is released.)
 *	3) If we are inside digest, then we'll ignore this key
 *	4) In any other mode, we'll quit whatever mode we were in and
 *	   enter SLOW mode.
 */
#ifdef BILINGUAL_OSD
PRIVATE void procFast(msg, c_msg, keyCode)
char *msg, *c_msg;
int keyCode;
#else
PRIVATE void procFast(msg, keyCode)
char *msg;
int keyCode;
#endif
{
    /* If we are in the middle of REP AB, then we'll reset it */
    if (stRepAB == 2) stRepAB = 0;

    if (playMode == MODE_FAST) {
	resetMode();
	if (!TDM_isCDDA)
	    cleanSystemState();
	OUTOSD(OSD_FUNCTION_STATUS_REGION, MSG_play, MSG_c_play, 5);
    } else if (playMode == MODE_PAUSE) {
	OUTOSD(OSD_FUNCTION_STATUS_REGION, msg, c_msg, 2);
    } else {
	if (scanMode == SCAN_OFF) {	/* Not in digest or anything */
	    resetMode();
	    tdmStopCopy = 0;	/* Just in case */
	    playMode = MODE_FAST;
	    OUTOSD(OSD_FUNCTION_STATUS_REGION, msg, c_msg, 0);
	    fast_key = keyCode;
	    fast_key_num = FAST_KEY_NUM;
	    vcx_fast_forward = 1;
	    vcx_playvideo_only = 1;
	    vcx_interupt_FrameCount = VID_frame_count + 1;
	    vcx_interupt_FrameCount_pause = VC_PAUSE;
	}
    }
}

/*
 * This routine is called when the INTRO (disc digest) key is pressed.
 *
 * The logic is as follows:
 *	1) If we are in normal play mode, we'll go to disc digest right away
 *	   (disc digest is to show 6 I-frame then go to the next track)
 *	2) If we are in FF/FB/SLOW mode, we'll quit the mode and enter
 *	   digest
 *	3) If we are in PAUSE mode, we'll enter track digest and start
 *	   playing by issuing a 'PLAY' key. Track digest is similar to
 *	   disc digest, but there is no skip after 6 I-frame.
 */
PRIVATE void procIntro()
{
    if (scanMode == SCAN_B) {
	if (playMode == MODE_PAUSE) 
	  OUTOSD(OSD_FUNCTION_STATUS_REGION, msgError, msgError, 2);
	else {	/* quit digest mode */
	    scanMode = SCAN_OFF;
	    digest2Normal();
	    CLEARALLOSD();
	    OUTOSD(OSD_FUNCTION_STATUS_REGION, MSG_play, MSG_c_play, 5);
	}
    } else {
	/*
	 * We don't go into digest if:
	 *	1) We are playing CDDA
	 *	2) We are in the middle of repeat A to B
	 *	3) We are in the middle of 10+ key ('NEXT' doesn't work!)
	 */
	if (TDM_isCDDA || (stRepAB != 0) || (cntTen != 0)) 
	  OUTOSD(OSD_FUNCTION_STATUS_REGION, msgError, msgError, 5);
	else {
	    /*
	     * Enter digest mode (keep PAUSE status)
	     */
	    scanMode = SCAN_B;
	    if (playMode == MODE_PAUSE) {
		resetSystem();
		/*
		 * Delay a little bit before sending the PLAY key
		 * since we just received INTRO, and if we send
		 * out key too fast, the external controller will
		 * most likely drop our key!
		 */
		IR_send_Play();
		viewTrack = 1;	/* Track view (vs. disc view) */
		ptrIntro = MSG_track_view;
#ifdef BILINGUAL_OSD
		c_ptrIntro = MSG_c_track_view;
#endif
	    } else {
		resetSystem();
		viewTrack = 0;	/* Disc view (vs. track view) */
		ptrIntro = MSG_disc_view;
#ifdef BILINGUAL_OSD
		c_ptrIntro = MSG_c_disc_view;
#endif
	    }
	    OUTOSD(OSD_DIGEST_REGION, ptrIntro, c_ptrIntro, 20);
	    digestPage(0);
	}
    }
}

/*
 * This routine is called when MUTE key is pressed.
 * 
 * The original volume level will be kept in a separate set of variables.
 * There is no other side effect.
 */
PRIVATE void procMute()
{
    muteAudio ^= 1;
    if (muteAudio)
	OUTOSD(OSD_AUDIO_REGION, MSG_mute, MSG_c_mute, 0);
    else
	OUTOSD(OSD_AUDIO_REGION, msgNull, msgNull, 0);
    if (muteAudio) {	/* Set to 0 */
	kptAudioLevel = audioLevel;
	audioLevel = 0;
	vcx_audio_volume = 0;
    } else {	/* Restore */
	audioLevel = kptAudioLevel;
	vcx_audio_volume = (int) (unsigned int) vcxVolume[audioLevel];
    }
}

/*
 * This routine is called when NEXT key is pressed.
 *
 * The logic is as follows:
 *	1) If we have pressed '10+' before, then 'NEXT' will show
 *	   the current '10+' information without going to the next track.
 *	2) Otherwise, if we are in 'PAUSE' mode, then we'll reset playMode 
 *	   to 'NORMAL'. In any case, CD goes to the next track and we
 *	   start to play from there.
 */
PRIVATE void procNext()
{
    /*
     * If we are in the middle of 10+ selection, "NEXT" is ignored
     * (customer may want to customize this)
     */
    if (cntTen) procTrack10Plus(0);
    else {
	OUTOSD(OSD_FUNCTION_STATUS_REGION, MSG_next, MSG_c_next, 5);

⌨️ 快捷键说明

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