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

📄 pbc.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    UBYTE        error;
    UBYTE        num;
    ULONG        offset;
    ULONG        msg[4];

    DBGPRINT(DBG_ON(DBG_TRACE), ("\n\npbc_play_end()\n\n"));

    error = 0;
    time = 0;

    /* clear the A-B repeat */
    if (A_B_count == 1)
    {
        A_B_count = 0;
        g_repeat_mode = REPEAT_OFF;
        msg[0] = VDVD_STATUS_REPEAT;
        msg[1] = VDVD_INFO_REPEAT_OFF;
        if (UsrEventHandler(msg) != USR_SUCCESS)
        {
            DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
        }
    }

    if ((pbc_mode == PBC_MODE_PLAY) || (pbc_mode == PBC_MODE_END) || (pbc_mode == PBC_MODE_HALT))
    {
        /* for PBC ON processing */
        if ((g_pbc_on == PBC_ON) && (g_repeat_mode != REPEAT_A_B))
        {
            /* stop FF/FB */
            if (g_play_kind == PKIND_FF)
            {
                PEiStreamCtrlResume(tPE);

                g_play_kind = PKIND_PLAY;
                ulPlaySpeed = 1000;

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

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

            /* track repeat? */
            if (g_repeat_mode == REPEAT_TT)
            {
                if ((g_track > 1) && (g_track != 0xff))
                {
                    com_tno_time_get(com_bintobcd(g_track), &s_msf[0], &e_msf[0]);
                    pbc_fe_playcd_req(0, 0, FEA_PLAY_CD_ABO, &s_msf[0], &e_msf[0]);
                }
            }
            else
            {
                /* go into END mode */
                pbc_mode    = PBC_MODE_END;
                g_play_kind = PKIND_PLAY;

                if (*g_current_psd == PLAY_LIST_HD)
                {
                    /* Play List */
                    pbcParsePlayList(&plist, g_current_psd);

                    time = pbc_get_waite_time(plist.play_wait_time);
                    if (time == 0)
                    {
                        ++pbc_play_item_num;

                        if (pbc_play_item_num >= plist.item_no)
                        {
                            offset = pbc_next_check();

                            if (offset != 0xFFFF)
                            {
                                /* jump to next list */
                                if (g_play_kind == PKIND_SLOW)
                                {
                                    msg[0] = VDVD_STATUS_PLAY;
                                    if (UsrEventHandler(msg) != USR_SUCCESS)
                                    {
                                        DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
                                    }
                                }

                                offset *= g_info_vcd.offset;
                                error = pbc_list_play(offset);

                                if (error)
                                {
                                    stop_on_error();
                                    return;
                                }
                            }
                            else
                            {
                                /* a next offset of 0xFFFF is illegal but there
                                discs with it so we will go into a stop mode */
                                msg[0] = VDVD_STATUS_STOP;
                                msg[1] = 2;
                                if (UsrEventHandler(msg) != USR_SUCCESS)
                                {
                                    DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
                                }
                                logo_display();
                                pbc_stop_com();
                            }
                        }
                        else
                        {
                            pin = plist.pin[pbc_play_item_num];    /* Get PIN */
                            pbc_play_item(pin, plist.play_time);   /* ITEM Play */
                        }
                    }
                    else if (time != 0x0FFFFFFFF)
                    {
                        pbc_waite_time_req(TIM_CONT_START, time);
                    }
                }
                else if (*g_current_psd == SELECT_LIST_HD)
                {
                    pbcParseSelectList(&slist, g_current_psd);

                    /*---< Jump Timing >---*/
                    if ((slist.loop_jump & 0x80) && (pbc_jump_key != 0x00))
                    {
                        tno = 0;

                        switch (pbc_jump_key)
                        {
                        case KEY_NEXT_PG:     /* NEXT */
                            offset = pbc_next_check();
                            tno = 1;
                            break;

                        case KEY_PREV_PG:     /* PREVIOUS */
                            offset = pbc_prev_check();
                            tno = 2;
                            break;

                        case KEY_RETURN:      /* RETURN */
                            offset = pbc_ret_check();
                            break;

                        case KEY_PLAY:        /* DEFAULT */
                            offset = pbc_default_check();
                            break;

                        case KEY_NUMBER:
                            offset = pbc_jump_num;
                            break;

                        default:
                            offset = 0xFFFF;
                            break;
                        }

                        pbc_jump_key = 0x00;
                        pbc_jump_num = 0x00;

                        if (offset != 0xFFFF)
                        {
                            /* do loop key jump */
                            offset *= g_info_vcd.offset;
                            error = pbc_list_play(offset);

                            if (error)
                            {
                                stop_on_error();
                            }
                            else
                            {
                                if (tno)
                                {
                                    msg[0] = VDVD_STATUS_CHAPTER_SKIP;
                                    msg[1] = g_scene;
                                    msg[2] = tno;
                                    if (UsrEventHandler(msg) != USR_SUCCESS)
                                    {
                                        DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
                                    }
                                }
                            }

                            pbc_end_flag = 0;
                            return;
                        }
                    }

                    /*---< Loop Count >---*/
                    if (pbc_loop_count == 0)
                    {   /* Infinite */
                        pbc_play_item(slist.pin, PLY_TIM_EOF);
                        pbc_end_flag = 0;
                        return;
                    }

                    pbc_loop_count--;

                    if (pbc_loop_count != 0)
                    {
                        /* Loop */
                        pbc_play_item(slist.pin, PLY_TIM_EOF);
                        pbc_end_flag = 0;
                        return;
                    }

                    /*---< Waite Time for Time-out >---*/
                    time = pbc_get_waite_time(slist.wait_time);

                    if (time == 0)
                    {
                        /* no timeout, jump immediately */
                        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 (time != 0xFFFFFFFF)
                    {
                        /* start the wait timer */
                        pbc_waite_time_req(TIM_CONT_START, time);
                        pbc_end_flag = 0;
                        return;
                    }
                }
            }
        }
        /* PBC OFF or REPEAT_A_B */
        else
        {
            if (g_random_mode != PMODE_NORMAL)
            {
                reset_play_point();
            }

            if (g_repeat_mode != REPEAT_A_B)
            {
                /* PBC is off so we just deal with track play */
                tno = cd_next_tno_get();

                if (tno != 0xFF)
                {
                    pbc_mode = PBC_MODE_PLAY;

                    g_track = tno;      /* play tno */
                    g_time[0] = 0;
                    g_time[1] = 0;

                    pbc_track_play(tno, PLY_TIM_EOF);
                }
                else
                {
                    /* end of disc, go to full stop */
                    msg[0] = VDVD_STATUS_STOP;
                    msg[1] = 2;
                    if (UsrEventHandler(msg) != USR_SUCCESS)
                    {
                        DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
                    }

                    logo_display();
                    pbc_stop_com();
                    goto errout;
                }
            }
            else
            {
                /* restart the A-B repeat */
                pbc_fe_playcd_req(0, 0, FEA_PLAY_CD_ABO, &a_msf[0], &b_msf[0]);
            }

            if (g_play_kind == PKIND_FF)
            {
                /* restart the VCD FF system after track cross */
                msg[0] = MSG_KEY;
                msg[1] = KEY_FWD_PLAY;
                msg[2] = ulPlaySpeed;

                OS_MsgQSend(queue_vcd, (char *)&msg[0], VCD_MSG_SIZE, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
            }
        }
    }

errout:

    pbc_end_flag = 0;
}


/*************************************************
    Function Name:  pbc_scene_play

    Purpose:    VCD scene play processing.

    Theory:     Determines the LOT offet for the
                desired scene.  Used only in PBC.

    Arguments:  none

    Returns:    Error code.

*************************************************/
UBYTE pbc_scene_play(void)
{
    ULONG offset = 0x0FFFF;  /* PSD offset */
    UBYTE error  = 0;

    DBGPRINT(DBG_ON(DBG_TRACE),("%s: Attempting to play scene %i\n", __FUNCTION__, g_scene));

    /* force a 0 offset for List ID 1, seen bizarre discs where the LOT had a funny offset */
    if (g_scene == 1)
    {
        offset = 0;
    }
    else
    {
        DbgPrint(("THE SCENE = %i, THE MAX LIST ID = %i\n", g_scene, g_info_vcd.max_list_id));
        if (g_scene <= g_info_vcd.max_list_id)
        {
            offset = g_lot_addr[g_scene];
        }
    }

    if (offset != 0x0FFFF)
    {
        offset *= g_info_vcd.offset;

        DbgPrint(("CALLING pbc_list_play, offset=0x%X\n", offset));
        error = pbc_list_play(offset);
    }

    return (error);
}

/*************************************************
    Function Name:  pbc_get_selection_no

    Purpose:    VCD entry selection.

    Theory:     Gets the next entry from the entry table.
	            This is used by the default system and hence
				is dependent on the current address.  The
				current address is compared between the
				various entries to find out which entry it is
				currently in and then returns that number.

    Arguments:  none

    Returns:    Selection number to play.

*************************************************/
USHORT pbc_get_selection_no(void)
{
  USHORT ei, sel_no;
  ULONG current, prev, next;

    for (ei = 0; ei < g_entry_vcd.entries_used; ++ei)
    {
        if (pbc_play_time[0] == g_entry_vcd.entry[ei].tno)
        {
            break;
        }
    }

    if (ei == g_entry_vcd.entries_used)
    {
        return (0x0FFFF);
    }

    current = com_tno_time_bcdtobin(&pbc_play_time[1]);
    prev = com_tno_time_bcdtobin(&g_entry_vcd.entry[ei].sector[0]);

    for (sel_no = 0; ei < g_entry_vcd.entries_used; ++sel_no, ++ei)
    {
        if (pbc_play_time[0] != g_entry_vcd.entry[ei + 1].tno)
        {
            break;
        }
        next = com_tno_time_bcdtobin(&g_entry_vcd.entry[ei + 1].sector[0]);
        if (current < next)
        {
            break;
        }
        prev = next;
    }

    return (sel_no);
}


/*************************************************
    Function Name:  pbc_default_check

    Purpose:    VCD default list check.

    Theory:     In PBC, in a selection list there
	            can be a default selection.  This
				returns the offset of the default
				selection list whether it's from
				the default list offset or the
				multi-default selection number.

⌨️ 快捷键说明

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