📄 pbc.cpp
字号:
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 + -