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

📄 pbc.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
    }
    else
    {   /* Play Nothing */
        ret = 0x0FFFF;
    }
    return (ret);
}

/*************************************************
    Function Name:  pbc_track_play

    Purpose:    Track play process.

    Theory:     Does the actual TOC parsing and issues
                play command to drive based on track
                number desired.

    Arguments:  none

    Returns:    Track number valid or invalid

*************************************************/
USHORT pbc_track_play(USHORT tno, USHORT ptime)
{
    ULONG playtime, start, end, msg[4];
    UBYTE bcd_tno;

    DBGPRINT(DBG_ON(DBG_ALL),("pbc_track_play: TNO = %i, ptime = %i\n", tno, ptime ));

    bcd_tno      = com_bintobcd((UBYTE) tno);

    if (com_tno_time_get(bcd_tno, &s_msf[0], &e_msf[0]) == OS_OK)
    {
        if ((cd_max_tno != cd_max_tno_cdda))
        {
            if (tno == cd_max_tno_cdda)
            {
                /* the CDDA tracks on a VCD 2.0 disc begin with a front margin of 375 sectors,
                 * this needs to be removed from the video play region */
                end = msf_modify(combine_msf(&e_msf[0]), 375, SUBTRACT_MSF);
                e_msf[0] = (UBYTE)((end & 0xFF0000) >> 16);
                e_msf[1] = (UBYTE)((end & 0xFF00) >> 8);
                e_msf[2] = (UBYTE)(end & 0xFF);
            }
        }


        if (ptime != PLY_TIM_EOF)
        {
            start = com_tno_time_bcdtobin(&s_msf[0]);
            playtime = (ULONG) ptime *5;

            start += (playtime - 1);
            com_tno_time_bintobcd(start, &e_msf[0]);
        }

        if (g_toc_info.tno[tno - 1].cont & TOC_CONTROL_FIELD_DATA_TRACK)
        {
            /* CD-ROM */
            cdda_track = 0;

            /* this is the usual path for vcd video playback */
            pbc_fe_playcd_req(PLAY_SET_PLAY, 0, FEA_PLAY_CD_ABO, &s_msf[0], &e_msf[0]);
        }
        else
        {   /* CD-DA Track */
            cdda_track = 1;

            pbc_fe_playcd_req(PLAY_SET_CDDA, 0, FEA_PLAY_CD_ABO, &s_msf[0], &e_msf[0]);
        }


        if (g_play_kind != PKIND_PLAY)
        {
            msg[0] = VDVD_STATUS_PLAY;
            if (UsrEventHandler(msg) != USR_SUCCESS)
            {
                DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
            }
        }
        g_play_kind = PKIND_PLAY;

        pbc_mode = PBC_MODE_PLAY;
        return (OS_OK);
    }

    return (0xffff);
}

/*************************************************
    Function Name:  pbc_entry_play

    Purpose:    Entry play process.

    Theory:     Determines the read length based on
                entry and track number, and then issues
                the read command to the drive.

    Arguments:  entry number, play time

    Returns:    valid entry number or not

*************************************************/
USHORT pbc_entry_play(USHORT entry, USHORT ptime)
{
    UBYTE tno, i;
    ULONG playtime, start;

    if (entry <= g_entry_vcd.entries_used)
    {
        tno = g_entry_vcd.entry[entry - 1].tno; /* TNO Get */

        com_tno_time_get(tno, &s_msf[0], &e_msf[0]);
        for (i = 0; i < 3; ++i)
        {
            s_msf[i] = g_entry_vcd.entry[entry - 1].sector[i];
        }
        if (ptime != PLY_TIM_EOF)
        {
            start = com_tno_time_bcdtobin(&s_msf[0]);
            playtime = (ULONG) ptime *5;

            start += (playtime - 1);
            com_tno_time_bintobcd(start, &e_msf[0]);
        }

        g_track = com_bcdtobin(tno);
        pbc_fe_playcd_req(PLAY_SET_PLAY, 0, FEA_PLAY_CD_ABO, &s_msf[0], &e_msf[0]);
        g_play_kind = PKIND_PLAY;
        pbc_mode = PBC_MODE_PLAY;

        return (OS_OK);
    }

    return (0xffff);
}

/*************************************************
    Function Name:  pbc_seg_play

    Purpose:    Segment play process.

    Theory:     Issues a read command to the drive
                based on the desired segment number

    Arguments:  segment number

    Returns:    nothing

*************************************************/
void pbc_seg_play(USHORT seg)
{
    ULONG s_time, e_time;
    USHORT i;

    DbgPrint(("\nPlaying segment %i\n", seg ));

    pbc_seg_item = g_info_vcd.seg_play_item[seg - 1];
    s_time = com_tno_time_bcdtobin(&g_info_vcd.fseg_addr[0]);
    s_time += (seg - 1) * 150;  /* 1seg=150sectors */
    e_time = s_time + 150;

    i = 1;
    while (1)
    {
        if (g_info_vcd.seg_play_item[(seg - 1) + i] & 0x20)
        {
            e_time += 150;      /* MULTI SEGMENT PLAY */
            ++i;
        }
        else
        {
            break;
        }
    }
    e_time -= 1;

    com_tno_time_bintobcd(s_time, &s_msf[0]);
    com_tno_time_bintobcd(e_time, &e_msf[0]);

    g_track = 1; /* segments can only be in track 1 */

    DbgPrint(("s[0]=%i, s[1]=%i, s[2]=%i\n", s_msf[0], s_msf[1], s_msf[2]));
    DbgPrint(("e[0]=%i, e[1]=%i, e[2]=%i\n", e_msf[0], e_msf[1], e_msf[2]));

    pbc_fe_playcd_req(PLAY_SET_PLAY, pbc_seg_item, FEA_PLAY_CD_ABO, &s_msf[0], &e_msf[0]);
    g_play_kind = PKIND_PLAY;

    pbc_mode = PBC_MODE_PLAY;
}

/*************************************************
    Function Name:  pbc_get_waite_time

    Purpose:    Determine proper wait time.

    Theory:     Based on the wait number from the
                selection lists, determine the correct
                time to wait during pauses.

    Arguments:  wait number

    Returns:    how long to wait (in seconds)

*************************************************/
ULONG pbc_get_waite_time(UBYTE wt)
{
    ULONG time;

    if (wt == 0)
    {
        time = 0;
    }
    else if (wt == 0x0FF)
    {
        time = 0x0FFFFFFFF;
    }
    else if (wt <= 60)
    {
        time = (ULONG) wt;
    }
    else
    {
        time = (wt - 60) * 10 + 60;
    }
    return (time);
}

/*************************************************
    Function Name:  pbc_loop_jump_chk

    Purpose:    Check for a loop jump.

    Theory:     Checks the selectionlist to see if
                a loop jump exists.

    Arguments:  nothing

    Returns:    valid loop jump or not

*************************************************/
UBYTE pbc_loop_jump_chk(void)
{
    SELECT_LIST slist;

    if (*g_current_psd == SELECT_LIST_HD)
    {
        /* Selection List */
        pbcParseSelectList(&slist, g_current_psd);

        /*---< Jump Timing >---*/
        if (slist.loop_jump & 0x80)
        {
            return (0xff);
        }
    }

    return (OS_OK);
}

/*************************************************
    Function Name:  pbc_timeout_proc

    Purpose:    Handle a timeout message from a timer.

    Arguments:  message passed in from task loop

    Returns:    nothing

*************************************************/
void pbc_timeout_proc()
{
    SELECT_LIST slist;
    PLAY_LIST   plist;
    ULONG       offset;
    USHORT      pin;
    USHORT      base;
    ULONG       msg_out[4];
    UBYTE       num;
    UBYTE       error;
    error = 0;

    /* wait timer for list timeout or auto-pause */
    DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_timeout_proc: TIM_PBC_PAUSE\n"));

    if (pbc_mode == PBC_MODE_END)
    {
        /* in END mode it has to be a list timeout, there are no trigger bits in END */
        if (*g_current_psd == PLAY_LIST_HD)
        {
            pbcParsePlayList(&plist, g_current_psd);
            ++pbc_play_item_num;
            if (pbc_play_item_num >= plist.item_no)
            {
                offset = pbc_next_check();      /* Next List Check */
                if (offset != 0x0FFFF)
                {
                    offset *= g_info_vcd.offset;

                    error = pbc_list_play(offset);
                    if (error)
                    {
                        stop_on_error();
                        return;
                    }
                }
            }
            else
            {
                pin = plist.pin[pbc_play_item_num];    /* Get PIN */
                pbc_play_item(pin, plist.play_time);   /* ITEM Play */
            }
        }
        else if (*g_current_psd == SELECT_LIST_HD)
        {
            pbcParseSelectList(&slist, g_current_psd );
            offset = slist.tout_list_off;      /* Time Out List Check */
            if (offset != 0x0FFFF)
            {
                offset *= g_info_vcd.offset;

                error = pbc_list_play(offset);
                if (error)
                {
                    stop_on_error();
                    return;
                }
            }
            else
            {
                if (slist.nos == 1)
                {
                    offset = slist.bsn_off[slist.bsn - 1];
                    if (offset != 0x0FFFF)
                    {
                        offset *= g_info_vcd.offset;

                        error = pbc_list_play(offset);
                        if (error)
                        {
                            stop_on_error();
                            return;
                        }
                    }
                }
                else
                {
                    base = slist.bsn - 1;
                    num = com_random_get(slist.nos);
                    offset = slist.bsn_off[(num - 1) - base];
                    if (offset != 0x0FFFF)
                    {
                        offset *= g_info_vcd.offset;

                        error = pbc_list_play(offset);
                        if (error)
                        {
                            stop_on_error();
                            return;
                        }
                    }
                }
            }
        }
    }
    else if (pbc_mode == PBC_MODE_PLAY)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_timeout_proc: PBC_MODE_PLAY\n"));

        /* in PLAY mode it must be an auto-pause from a trigger bit */
        if ((pbc_apause_tim) && /* Auto Pause */
            (g_play_kind == PKIND_PAUSE))
        {
            g_play_kind = PKIND_PLAY;
            ulPlaySpeed = 1000;
            PEiStreamCtrlResume(tPE);
            msg_out[0] = VDVD_STATUS_PLAY;
            if (UsrEventHandler(msg_out) != USR_SUCCESS)
            {
                DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
            }
        }
    }
}


/*
 * play_location
 *      play a location from the location structure.
 *      used to implement bookmarking
 */
void play_location(NAV_VCD_LOCATION *pLocation)
{
    ULONG msg[4];
    UBYTE location[4];
    ULONG locparam;

    if (pLocation != NULL)
    {
        if (pbc_mode != PBC_MODE_STOP)
        {
            /* if not already stopped, get to the fullstop state */
            msg[0] = VDVD_STATUS_STOP;
            msg[1] = 1;
            if (UsrEventHandler(msg) != USR_SUCCESS)
            {
                DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
            }

            pbc_stop_com();
        }

        /*
         * Read bookmark data from location handle
         */
        pbc_mode    = pLocation->rsm.pbc_mode;
        g_pbc_on    = pLocation->rsm.g_pbc_on;
        g_track     = pLocation->rsm.g_track;
        g_scene     = pLocation->rsm.g_scene;
        location[0] = pLocation->rsm.pbc_play_time[0];
        location[1] = pLocation->rsm.pbc_play_time[1];
        location[2] = pLocation->rsm.pbc_play_time[2];
        location[3] = pLocation->rsm.pbc_play_time[3];

        //what do do with this?
        //g_random_mode = PMODE_NORMAL;


        if (g_pbc_on && (g_track == 1) )
        {
            pbc_scene_play();
        }
        else
        {
            locparam = com_tno_time_bcdtobin(&location[1]) / 75;

            pbc_timesearch(TRUE, locparam);
        }

    }
    else
    {
        DbgPrint(("Location handle is NULL!"));
    }
}



/*************************************************
    Function Name:  pbc_key_proc

    Purpose:    Passes key input.

    Theory:     Passes user key input based on the current
                play state

    Arguments:  message from task loop

⌨️ 快捷键说明

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